import net.pterodactylus.sone.data.Sone;
import net.pterodactylus.sone.data.Sone.ShowCustomAvatars;
import net.pterodactylus.sone.data.Sone.SoneStatus;
+import net.pterodactylus.sone.data.TemporaryImage;
import net.pterodactylus.sone.database.PostBuilder;
-import net.pterodactylus.sone.database.PostBuilderFactory;
+import net.pterodactylus.sone.database.PostDatabase;
import net.pterodactylus.sone.database.PostProvider;
import net.pterodactylus.sone.database.PostReplyBuilder;
import net.pterodactylus.sone.database.PostReplyBuilderFactory;
import net.pterodactylus.sone.database.PostReplyProvider;
import net.pterodactylus.sone.database.SoneProvider;
-import net.pterodactylus.sone.data.TemporaryImage;
import net.pterodactylus.sone.fcp.FcpInterface;
import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired;
import net.pterodactylus.sone.freenet.wot.Identity;
/** All known Sones. */
private final Set<String> knownSones = new HashSet<String>();
- /** The post builder. */
- private final PostBuilderFactory postBuilderFactory;
-
- /** All posts. */
- private final Map<String, Post> posts = new HashMap<String, Post>();
-
- /** All known posts. */
- private final Set<String> knownPosts = new HashSet<String>();
+ /** The post database. */
+ private final PostDatabase postDatabase;
/** The post reply builder factory. */
private final PostReplyBuilderFactory postReplyBuilderFactory;
* The WebOfTrust updater
* @param eventBus
* The event bus
- * @param postBuilderFactory
- * The post builder
+ * @param postDatabase
+ * The post database
* @param postReplyBuilderFactory
* The post reply builder factory
*/
@Inject
- public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, PostBuilderFactory postBuilderFactory, PostReplyBuilderFactory postReplyBuilderFactory) {
+ public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, PostDatabase postDatabase, PostReplyBuilderFactory postReplyBuilderFactory) {
super("Sone Core");
this.configuration = configuration;
this.freenetInterface = freenetInterface;
this.updateChecker = new UpdateChecker(eventBus, freenetInterface);
this.webOfTrustUpdater = webOfTrustUpdater;
this.eventBus = eventBus;
- this.postBuilderFactory = postBuilderFactory;
+ this.postDatabase = postDatabase;
this.postReplyBuilderFactory = postReplyBuilderFactory;
}
* @return A new post builder
*/
public PostBuilder postBuilder() {
- return postBuilderFactory.newPostBuilder();
+ return postDatabase.newPostBuilder();
}
/**
*/
@Override
public Optional<Post> getPost(String postId) {
- synchronized (posts) {
- return Optional.fromNullable(posts.get(postId));
- }
+ return postDatabase.getPost(postId);
}
/**
@Override
public Collection<Post> getDirectedPosts(final String recipientId) {
checkNotNull(recipientId, "recipient must not be null");
- synchronized (posts) {
- return Collections2.filter(posts.values(), new Predicate<Post>() {
-
- @Override
- public boolean apply(Post post) {
- return recipientId.equals(post.getRecipientId().orNull());
- }
- });
- }
+ return postDatabase.getDirectedPosts(recipientId);
}
/**
logger.log(Level.FINE, String.format("Downloaded Sone %s is not newer than stored Sone %s.", sone, storedSone));
return;
}
- synchronized (posts) {
- if (!soneRescueMode) {
- for (Post post : storedSone.get().getPosts()) {
- posts.remove(post.getId());
- if (!sone.getPosts().contains(post)) {
- eventBus.post(new PostRemovedEvent(post));
- }
- }
+ /* find removed posts. */
+ Collection<Post> existingPosts = postDatabase.getPosts(sone.getId());
+ for (Post oldPost : existingPosts) {
+ if (!sone.getPosts().contains(oldPost)) {
+ eventBus.post(new PostRemovedEvent(oldPost));
}
- List<Post> storedPosts = storedSone.get().getPosts();
- synchronized (knownPosts) {
- for (Post post : sone.getPosts()) {
- post.setKnown(knownPosts.contains(post.getId()));
- if (!storedPosts.contains(post)) {
- if (post.getTime() < getSoneFollowingTime(sone)) {
- knownPosts.add(post.getId());
- post.setKnown(true);
- } else if (!knownPosts.contains(post.getId())) {
- eventBus.post(new NewPostFoundEvent(post));
- }
- }
- posts.put(post.getId(), post);
- }
+ }
+ /* find new posts. */
+ for (Post newPost : sone.getPosts()) {
+ if (existingPosts.contains(newPost)) {
+ continue;
+ }
+ if (newPost.getTime() < getSoneFollowingTime(sone)) {
+ newPost.setKnown(true);
+ } else if (!newPost.isKnown()) {
+ eventBus.post(new NewPostFoundEvent(newPost));
}
}
+ /* store posts. */
+ postDatabase.storePosts(sone, sone.getPosts());
synchronized (replies) {
if (!soneRescueMode) {
for (PostReply reply : storedSone.get().getReplies()) {
knownSones.add(friend);
}
}
- synchronized (this.posts) {
- for (Post post : posts) {
- this.posts.put(post.getId(), post);
- }
- }
- synchronized (knownPosts) {
- for (Post post : posts) {
- knownPosts.add(post.getId());
- }
+ postDatabase.storePosts(sone, posts);
+ for (Post post : posts) {
+ post.setKnown(true);
}
synchronized (this.replies) {
for (PostReply postReply : replies) {
logger.log(Level.FINE, String.format("Tried to create post for non-local Sone: %s", sone));
return null;
}
- PostBuilder postBuilder = postBuilderFactory.newPostBuilder();
+ PostBuilder postBuilder = postDatabase.newPostBuilder();
postBuilder.from(sone.getId()).randomId().withTime(time).withText(text.trim());
if (recipient.isPresent()) {
postBuilder.to(recipient.get().getId());
}
final Post post = postBuilder.build();
- synchronized (posts) {
- posts.put(post.getId(), post);
- }
+ postDatabase.storePost(post);
eventBus.post(new NewPostFoundEvent(post));
sone.addPost(post);
touchConfiguration();
logger.log(Level.WARNING, String.format("Tried to delete post of non-local Sone: %s", post.getSone()));
return;
}
- post.getSone().removePost(post);
- synchronized (posts) {
- posts.remove(post.getId());
- }
+ postDatabase.removePost(post);
eventBus.post(new PostRemovedEvent(post));
markPostKnown(post);
touchConfiguration();
*/
public void markPostKnown(Post post) {
post.setKnown(true);
- synchronized (knownPosts) {
- eventBus.post(new MarkPostKnownEvent(post));
- if (knownPosts.add(post.getId())) {
- touchConfiguration();
- }
- }
+ eventBus.post(new MarkPostKnownEvent(post));
+ touchConfiguration();
for (PostReply reply : getReplies(post)) {
markReplyKnown(reply);
}
}
/* save known posts. */
- int postCounter = 0;
- synchronized (knownPosts) {
- for (String knownPostId : knownPosts) {
- configuration.getStringValue("KnownPosts/" + postCounter++ + "/ID").setValue(knownPostId);
- }
- configuration.getStringValue("KnownPosts/" + postCounter + "/ID").setValue(null);
- }
+ postDatabase.saveKnownPosts(configuration, "KnownPosts/");
/* save known replies. */
int replyCounter = 0;
}
/* load known posts. */
- int postCounter = 0;
- while (true) {
- String knownPostId = configuration.getStringValue("KnownPosts/" + postCounter++ + "/ID").getValue(null);
- if (knownPostId == null) {
- break;
- }
- synchronized (knownPosts) {
- knownPosts.add(knownPostId);
- }
- }
+ postDatabase.loadKnownPosts(configuration, "KnownPosts/");
/* load known replies. */
int replyCounter = 0;
/* TODO - we don’t have the Sone anymore. should this happen? */
return;
}
- synchronized (posts) {
- synchronized (knownPosts) {
- for (Post post : sone.get().getPosts()) {
- posts.remove(post.getId());
- eventBus.post(new PostRemovedEvent(post));
- }
- }
+ postDatabase.removePosts(sone.get());
+ for (Post post : sone.get().getPosts()) {
+ eventBus.post(new PostRemovedEvent(post));
}
synchronized (replies) {
synchronized (knownReplies) {
import net.pterodactylus.sone.data.impl.DefaultPostBuilderFactory;
import net.pterodactylus.sone.data.impl.DefaultPostReplyBuilderFactory;
import net.pterodactylus.sone.database.PostBuilderFactory;
+import net.pterodactylus.sone.database.PostDatabase;
import net.pterodactylus.sone.database.PostProvider;
import net.pterodactylus.sone.database.PostReplyBuilderFactory;
import net.pterodactylus.sone.database.SoneProvider;
+import net.pterodactylus.sone.database.memory.MemoryPostDatabase;
import net.pterodactylus.sone.fcp.FcpInterface;
import net.pterodactylus.sone.freenet.PluginStoreConfigurationBackend;
import net.pterodactylus.sone.freenet.plugin.PluginConnector;
@Override
protected void configure() {
bind(Core.class).in(Singleton.class);
+ bind(MemoryPostDatabase.class).in(Singleton.class);
bind(EventBus.class).toInstance(eventBus);
bind(Configuration.class).toInstance(startConfiguration);
bind(FreenetInterface.class).in(Singleton.class);
bind(String.class).annotatedWith(Names.named("WebOfTrustContext")).toInstance("Sone");
bind(SonePlugin.class).toInstance(SonePlugin.this);
bind(FcpInterface.class).in(Singleton.class);
- bind(PostBuilderFactory.class).to(DefaultPostBuilderFactory.class).in(Singleton.class);
+ bind(PostDatabase.class).to(MemoryPostDatabase.class);
+ bind(PostBuilderFactory.class).to(MemoryPostDatabase.class);
bind(PostReplyBuilderFactory.class).to(DefaultPostReplyBuilderFactory.class).in(Singleton.class);
bind(SoneProvider.class).to(Core.class).in(Singleton.class);
- bind(PostProvider.class).to(Core.class).in(Singleton.class);
+ bind(PostProvider.class).to(MemoryPostDatabase.class);
bindListener(Matchers.any(), new TypeListener() {
@Override