From 6b7b300eda315485c9d70ad1f8739bdf11f9bd30 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Fri, 18 Jan 2013 14:36:37 +0100 Subject: [PATCH] Add builder for post replies. --- .../java/net/pterodactylus/sone/core/Core.java | 45 +++++---- .../pterodactylus/sone/core/SoneDownloader.java | 6 +- .../pterodactylus/sone/data/PostReplyBuilder.java | 59 +++++++++++ .../sone/data/PostReplyBuilderFactory.java | 34 +++++++ .../net/pterodactylus/sone/data/ReplyBuilder.java | 85 ++++++++++++++++ .../sone/data/impl/AbstractReplyBuilder.java | 112 +++++++++++++++++++++ .../data/impl/DefaultPostReplyBuilderFactory.java | 38 +++++++ .../sone/data/impl/PostReplyBuilderImpl.java | 69 +++++++++++++ .../net/pterodactylus/sone/main/SonePlugin.java | 3 + 9 files changed, 429 insertions(+), 22 deletions(-) create mode 100644 src/main/java/net/pterodactylus/sone/data/PostReplyBuilder.java create mode 100644 src/main/java/net/pterodactylus/sone/data/PostReplyBuilderFactory.java create mode 100644 src/main/java/net/pterodactylus/sone/data/ReplyBuilder.java create mode 100644 src/main/java/net/pterodactylus/sone/data/impl/AbstractReplyBuilder.java create mode 100644 src/main/java/net/pterodactylus/sone/data/impl/DefaultPostReplyBuilderFactory.java create mode 100644 src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index 5ce01fe..fe7f6ac 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -59,6 +59,8 @@ import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.PostBuilder; import net.pterodactylus.sone.data.PostBuilderFactory; import net.pterodactylus.sone.data.PostReply; +import net.pterodactylus.sone.data.PostReplyBuilder; +import net.pterodactylus.sone.data.PostReplyBuilderFactory; import net.pterodactylus.sone.data.Profile; import net.pterodactylus.sone.data.Profile.Field; import net.pterodactylus.sone.data.Reply; @@ -66,7 +68,6 @@ 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.data.impl.PostReplyImpl; import net.pterodactylus.sone.fcp.FcpInterface; import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired; import net.pterodactylus.sone.freenet.wot.Identity; @@ -178,6 +179,9 @@ public class Core extends AbstractService implements SoneProvider, PostProvider /** All known posts. */ private final Set knownPosts = new HashSet(); + /** The post reply builder factory. */ + private final PostReplyBuilderFactory postReplyBuilderFactory; + /** All replies. */ private final Map replies = new HashMap(); @@ -221,9 +225,11 @@ public class Core extends AbstractService implements SoneProvider, PostProvider * The event bus * @param postBuilderFactory * The post builder + * @param postReplyBuilderFactory + * The post reply builder factory */ @Inject - public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, PostBuilderFactory postBuilderFactory) { + public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, PostBuilderFactory postBuilderFactory, PostReplyBuilderFactory postReplyBuilderFactory) { super("Sone Core"); this.configuration = configuration; this.freenetInterface = freenetInterface; @@ -234,6 +240,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider this.webOfTrustUpdater = webOfTrustUpdater; this.eventBus = eventBus; this.postBuilderFactory = postBuilderFactory; + this.postReplyBuilderFactory = postReplyBuilderFactory; } // @@ -558,6 +565,15 @@ public class Core extends AbstractService implements SoneProvider, PostProvider } /** + * Returns a post reply builder. + * + * @return A new post reply builder + */ + public PostReplyBuilder postReplyBuilder() { + return postReplyBuilderFactory.newPostReplyBuilder(); + } + + /** * Returns the reply with the given ID. * * @param replyId @@ -1319,7 +1335,9 @@ public class Core extends AbstractService implements SoneProvider, PostProvider logger.log(Level.WARNING, "Invalid reply found, aborting load!"); return; } - replies.add(getPostReply(replyId, true).setSone(sone).setPost(getPost(postId)).setTime(replyTime).setText(replyText)); + PostReplyBuilder postReplyBuilder = postReplyBuilderFactory.newPostReplyBuilder(); + postReplyBuilder.withId(replyId).from(sone).to(getPost(postId)).withTime(replyTime).withText(replyText); + replies.add(postReplyBuilder.build()); } /* load post likes. */ @@ -1644,30 +1662,15 @@ public class Core extends AbstractService implements SoneProvider, PostProvider * @return The created reply */ public PostReply createReply(Sone sone, Post post, String text) { - return createReply(sone, post, System.currentTimeMillis(), text); - } - - /** - * Creates a new reply. - * - * @param sone - * The Sone that creates the reply - * @param post - * The post that this reply refers to - * @param time - * The time of the reply - * @param text - * The text of the reply - * @return The created reply - */ - public PostReply createReply(Sone sone, Post post, long time, String text) { checkNotNull(text, "text must not be null"); checkArgument(text.trim().length() > 0, "text must not be empty"); if (!sone.isLocal()) { logger.log(Level.FINE, String.format("Tried to create reply for non-local Sone: %s", sone)); return null; } - final PostReply reply = new PostReplyImpl(sone, post, System.currentTimeMillis(), text.trim()); + PostReplyBuilder postReplyBuilder = postReplyBuilderFactory.newPostReplyBuilder(); + postReplyBuilder.randomId().from(sone).to(post).currentTime().withText(text.trim()); + final PostReply reply = postReplyBuilder.build(); synchronized (replies) { replies.put(reply.getId(), reply); } diff --git a/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java b/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java index 36b672c..51bc6fd 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java @@ -33,6 +33,7 @@ import net.pterodactylus.sone.data.Image; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.PostBuilder; import net.pterodactylus.sone.data.PostReply; +import net.pterodactylus.sone.data.PostReplyBuilder; import net.pterodactylus.sone.data.Profile; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.data.Sone.SoneStatus; @@ -406,7 +407,10 @@ public class SoneDownloader extends AbstractService { return null; } try { - replies.add(core.getPostReply(replyId, true).setSone(sone).setPost(core.getPost(replyPostId)).setTime(Long.parseLong(replyTime)).setText(replyText)); + PostReplyBuilder postReplyBuilder = core.postReplyBuilder(); + /* TODO - parse time correctly. */ + postReplyBuilder.withId(replyId).from(sone).to(core.getPost(replyPostId)).withTime(Long.parseLong(replyTime)).withText(replyText); + replies.add(postReplyBuilder.build()); } catch (NumberFormatException nfe1) { /* TODO - mark Sone as bad. */ logger.log(Level.WARNING, String.format("Downloaded reply for Sone %s with invalid time: %s", sone, replyTime)); diff --git a/src/main/java/net/pterodactylus/sone/data/PostReplyBuilder.java b/src/main/java/net/pterodactylus/sone/data/PostReplyBuilder.java new file mode 100644 index 0000000..6c3e236 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/PostReplyBuilder.java @@ -0,0 +1,59 @@ +/* + * Sone - PostReplyBuilder.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.sone.data; + +/** + * Builder for a {@link PostReply} object. + * + * @author David ‘Bombe’ Roden + */ +public interface PostReplyBuilder extends ReplyBuilder { + + /** + * Configures this builder to set the given post as post the created reply + * refers to. + * + * @param post + * The post the reply refers to + * @return This builder + */ + public PostReplyBuilder to(Post post); + + /** + * Verifies the configuration of this builder and creates a new post reply. + *

+ * The following conditions must be met in order for the configuration to be + * considered valid: + *

    + *
  • Exactly one of {@link #randomId()} or {@link #withId(String)} must + * have been called.
  • + *
  • The {@link #from(Sone) sender} must not be {@code null}.
  • + *
  • Exactly one of {@link #currentTime()} or {@link #withTime(long)} must + * have been called.
  • + *
  • The {@link #withText(String) text} must not be {@code null} and must + * contain something other than whitespace.
  • + *
  • The {@link #to(Post) post} have been set.
  • + *
+ * + * @return The created post reply + * @throws IllegalStateException + * if this builder’s configuration is not valid + */ + public PostReply build() throws IllegalStateException; + +} diff --git a/src/main/java/net/pterodactylus/sone/data/PostReplyBuilderFactory.java b/src/main/java/net/pterodactylus/sone/data/PostReplyBuilderFactory.java new file mode 100644 index 0000000..17a92f3 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/PostReplyBuilderFactory.java @@ -0,0 +1,34 @@ +/* + * Sone - PostReplyBuilderFactory.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.sone.data; + +/** + * Factory for {@link PostReplyBuilder}s. + * + * @author David ‘Bombe’ Roden + */ +public interface PostReplyBuilderFactory { + + /** + * Creates a new post reply builder. + * + * @return A new post reply builder + */ + public PostReplyBuilder newPostReplyBuilder(); + +} diff --git a/src/main/java/net/pterodactylus/sone/data/ReplyBuilder.java b/src/main/java/net/pterodactylus/sone/data/ReplyBuilder.java new file mode 100644 index 0000000..53f3153 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/ReplyBuilder.java @@ -0,0 +1,85 @@ +/* + * Sone - ReplyBuilder.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.sone.data; + +/** + * Methods that all reply builders need to implement in order to be able to + * create any kind of {@link Reply}. + * + * @param + * The type of the builder + * @author David ‘Bombe’ Roden + */ +public interface ReplyBuilder> { + + /** + * Configures this builder to use a random ID when creating the reply. If + * this method is used, {@link #withId(String)} must not be used. + * + * @return This builder + */ + public B randomId(); + + /** + * Configures this builder to use the given ID when creating the reply. If + * this method is used, {@link #randomId()} must not be used. + * + * @param id + * The ID of the reply + * @return This builder + */ + public B withId(String id); + + /** + * Configures this builder to use the given {@link Sone} as sender of the + * reply. + * + * @param sender + * The sender of the reply + * @return This builder + */ + public B from(Sone sender); + + /** + * Configures this builder to use the current time when creating the reply. + * If this method is used, {@link #withTime(long)} must not be used. + * + * @return This builder + */ + public B currentTime(); + + /** + * Configures this builder to use the given time when creating the reply. If + * this method is used, {@link #currentTime()} must not be used. + * + * @param time + * The time of the reply + * @return This builder + */ + public B withTime(long time); + + /** + * Configures this builder to use the given text when creating the reply. + * + * @param text + * The text of the reply + * @return This builder + */ + public B withText(String text); + +} diff --git a/src/main/java/net/pterodactylus/sone/data/impl/AbstractReplyBuilder.java b/src/main/java/net/pterodactylus/sone/data/impl/AbstractReplyBuilder.java new file mode 100644 index 0000000..77e484a --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/impl/AbstractReplyBuilder.java @@ -0,0 +1,112 @@ +/* + * Sone - ReplyBuilder.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.sone.data.impl; + +import net.pterodactylus.sone.data.ReplyBuilder; +import net.pterodactylus.sone.data.Sone; + +/** + * Abstract implementation of a {@link ReplyBuilder}. + * + * @param + * The concrete implementation of the builder + * @param + * The interface implemented and exposed by the builder + * @author David ‘Bombe’ Roden + */ +public class AbstractReplyBuilder, B extends ReplyBuilder> implements ReplyBuilder { + + /** Whether to use a random ID for the reply. */ + protected boolean randomId; + + /** The ID of the reply. */ + protected String id; + + /** The sender of the reply. */ + protected Sone sender; + + /** Whether to use the current time when creating the reply. */ + protected boolean currentTime; + + /** The time of the reply. */ + protected long time; + + /** The text of the reply. */ + protected String text; + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public B randomId() { + this.randomId = true; + return (B) this; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public B withId(String id) { + this.id = id; + return (B) this; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public B from(Sone sender) { + this.sender = sender; + return (B) this; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public B currentTime() { + this.currentTime = true; + return (B) this; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public B withTime(long time) { + this.time = time; + return (B) this; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public B withText(String text) { + this.text = text; + return (B) this; + } + +} diff --git a/src/main/java/net/pterodactylus/sone/data/impl/DefaultPostReplyBuilderFactory.java b/src/main/java/net/pterodactylus/sone/data/impl/DefaultPostReplyBuilderFactory.java new file mode 100644 index 0000000..efe3c30 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/impl/DefaultPostReplyBuilderFactory.java @@ -0,0 +1,38 @@ +/* + * Sone - DefaultPostReplyBuilderFactory.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.sone.data.impl; + +import net.pterodactylus.sone.data.PostReplyBuilder; +import net.pterodactylus.sone.data.PostReplyBuilderFactory; + +/** + * {@link PostReplyBuilderFactory} that creates {@link PostReplyBuilderImpl}s. + * + * @author David ‘Bombe’ Roden + */ +public class DefaultPostReplyBuilderFactory implements PostReplyBuilderFactory { + + /** + * {@inheritDoc} + */ + @Override + public PostReplyBuilder newPostReplyBuilder() { + return new PostReplyBuilderImpl(); + } + +} diff --git a/src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java b/src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java new file mode 100644 index 0000000..756f28e --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java @@ -0,0 +1,69 @@ +/* + * Sone - PostReplyBuilderImpl.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.sone.data.impl; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.UUID; + +import net.pterodactylus.sone.data.Post; +import net.pterodactylus.sone.data.PostReply; +import net.pterodactylus.sone.data.PostReplyBuilder; + +import org.apache.commons.lang.StringUtils; + +/** + * {@link PostReplyBuilder} implementation that creates {@link PostReplyImpl} + * objects. + * + * @author David ‘Bombe’ Roden + */ +public class PostReplyBuilderImpl extends AbstractReplyBuilder implements PostReplyBuilder { + + /** The post the created reply refers to. */ + private Post post; + + /** + * {@inheritDoc} + */ + @Override + public PostReplyBuilder to(Post post) { + this.post = post; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public PostReply build() { + checkState((randomId && (id == null)) || (!randomId && (id != null)), "either random ID nor custom ID must be set"); + checkState(sender != null, "sender must not be null"); + checkState((currentTime && (time == 0)) || (!currentTime && (time >= 0)), "either current time or custom time must be set"); + checkState(!StringUtils.isBlank(text), "text must not be empty"); + checkState(post != null, "post must not be null"); + + /* create new post reply. */ + PostReplyImpl postReplyImpl = new PostReplyImpl(randomId ? UUID.randomUUID().toString() : id); + postReplyImpl.setSone(sender); + postReplyImpl.setPost(post); + postReplyImpl.setTime(currentTime ? System.currentTimeMillis() : time); + postReplyImpl.setText(text); + return postReplyImpl; + } +} diff --git a/src/main/java/net/pterodactylus/sone/main/SonePlugin.java b/src/main/java/net/pterodactylus/sone/main/SonePlugin.java index 1080818..152a70f 100644 --- a/src/main/java/net/pterodactylus/sone/main/SonePlugin.java +++ b/src/main/java/net/pterodactylus/sone/main/SonePlugin.java @@ -26,7 +26,9 @@ import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.core.FreenetInterface; import net.pterodactylus.sone.core.WebOfTrustUpdater; import net.pterodactylus.sone.data.PostBuilderFactory; +import net.pterodactylus.sone.data.PostReplyBuilderFactory; import net.pterodactylus.sone.data.impl.DefaultPostBuilderFactory; +import net.pterodactylus.sone.data.impl.DefaultPostReplyBuilderFactory; import net.pterodactylus.sone.fcp.FcpInterface; import net.pterodactylus.sone.freenet.PluginStoreConfigurationBackend; import net.pterodactylus.sone.freenet.plugin.PluginConnector; @@ -220,6 +222,7 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr bind(SonePlugin.class).toInstance(SonePlugin.this); bind(FcpInterface.class).in(Singleton.class); bind(PostBuilderFactory.class).to(DefaultPostBuilderFactory.class).in(Singleton.class); + bind(PostReplyBuilderFactory.class).to(DefaultPostReplyBuilderFactory.class).in(Singleton.class); bindListener(Matchers.any(), new TypeListener() { @Override -- 2.7.4