/*
- * Sone - SoneImpl.java - Copyright Ā© 2010ā2015 David Roden
+ * Sone - SoneImpl.java - Copyright Ā© 2010ā2019 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
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.logging.Logger.getLogger;
import java.net.MalformedURLException;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import net.pterodactylus.sone.data.Album;
import net.pterodactylus.sone.data.Client;
import net.pterodactylus.sone.data.Post;
* {@link Sone} implementation.
* <p/>
* Operations that modify the Sone need to synchronize on the Sone in question.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David āBombeā Roden</a>
*/
public class SoneImpl implements Sone {
private volatile boolean known;
/** All posts. */
- private final Set<Post> posts = new CopyOnWriteArraySet<Post>();
+ private final Set<Post> posts = new CopyOnWriteArraySet<>();
/** All replies. */
- private final Set<PostReply> replies = new CopyOnWriteArraySet<PostReply>();
+ private final Set<PostReply> replies = new CopyOnWriteArraySet<>();
/** The IDs of all liked posts. */
- private final Set<String> likedPostIds = new CopyOnWriteArraySet<String>();
+ private final Set<String> likedPostIds = new CopyOnWriteArraySet<>();
/** The IDs of all liked replies. */
- private final Set<String> likedReplyIds = new CopyOnWriteArraySet<String>();
+ private final Set<String> likedReplyIds = new CopyOnWriteArraySet<>();
/** The root album containing all albums. */
private final Album rootAlbum = new AlbumImpl(this);
*
* @return The identity of this Sone
*/
+ @Nonnull
public String getId() {
return id;
}
*
* @return The identity of this Sone
*/
+ @Nonnull
public Identity getIdentity() {
return identity;
}
*
* @return The name of this Sone
*/
+ @Nonnull
public String getName() {
return (identity != null) ? identity.getNickname() : null;
}
*
* @return The request URI of this Sone
*/
+ @Nonnull
public FreenetURI getRequestUri() {
try {
return new FreenetURI(getIdentity().getRequestUri())
*
* @return The insert URI of this Sone
*/
+ @Nullable
public FreenetURI getInsertUri() {
if (!isLocal()) {
return null;
* The time of the update (in milliseconds since Jan 1, 1970 UTC)
* @return This Sone (for method chaining)
*/
+ @Nonnull
public Sone setTime(long time) {
this.time = time;
return this;
*
* @return The status of this Sone
*/
+ @Nonnull
public SoneStatus getStatus() {
return status;
}
* @throws IllegalArgumentException
* if {@code status} is {@code null}
*/
- public Sone setStatus(SoneStatus status) {
+ @Nonnull
+ public Sone setStatus(@Nonnull SoneStatus status) {
this.status = checkNotNull(status, "status must not be null");
return this;
}
*
* @return A copy of the profile
*/
+ @Nonnull
public Profile getProfile() {
return new Profile(profile);
}
* @param profile
* The profile to set
*/
- public void setProfile(Profile profile) {
+ public void setProfile(@Nonnull Profile profile) {
this.profile = new Profile(profile);
}
*
* @return The client used by this Sone, or {@code null}
*/
+ @Nullable
public Client getClient() {
return client;
}
* The client used by this Sone, or {@code null}
* @return This Sone (for method chaining)
*/
- public Sone setClient(Client client) {
+ @Nonnull
+ public Sone setClient(@Nullable Client client) {
this.client = client;
return this;
}
* {@code true} if this Sone is known, {@code false} otherwise
* @return This Sone
*/
+ @Nonnull
public Sone setKnown(boolean known) {
this.known = known;
return this;
*
* @return The friend Sones of this Sone
*/
+ @Nonnull
public Collection<String> getFriends() {
return database.getFriends(this);
}
* @return {@code true} if this Sone has the given Sone as a friend, {@code
* false} otherwise
*/
- public boolean hasFriend(String friendSoneId) {
+ public boolean hasFriend(@Nonnull String friendSoneId) {
return database.isFriend(this, friendSoneId);
}
*
* @return All posts of this Sone
*/
+ @Nonnull
public List<Post> getPosts() {
List<Post> sortedPosts;
synchronized (this) {
- sortedPosts = new ArrayList<Post>(posts);
+ sortedPosts = new ArrayList<>(posts);
}
- Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
+ Collections.sort(sortedPosts, Post.NEWEST_FIRST);
return sortedPosts;
}
* The new (and only) posts of this Sone
* @return This Sone (for method chaining)
*/
- public Sone setPosts(Collection<Post> posts) {
+ @Nonnull
+ public Sone setPosts(@Nonnull Collection<Post> posts) {
synchronized (this) {
this.posts.clear();
this.posts.addAll(posts);
* @param post
* The post to add
*/
- public void addPost(Post post) {
+ public void addPost(@Nonnull Post post) {
if (post.getSone().equals(this) && posts.add(post)) {
logger.log(Level.FINEST, String.format("Adding %s to ā%sā.", post, getName()));
}
* @param post
* The post to remove
*/
- public void removePost(Post post) {
+ public void removePost(@Nonnull Post post) {
if (post.getSone().equals(this)) {
posts.remove(post);
}
*
* @return All replies this Sone made
*/
+ @Nonnull
public Set<PostReply> getReplies() {
return Collections.unmodifiableSet(replies);
}
* The new (and only) replies of this Sone
* @return This Sone (for method chaining)
*/
- public Sone setReplies(Collection<PostReply> replies) {
+ @Nonnull
+ public Sone setReplies(@Nonnull Collection<PostReply> replies) {
this.replies.clear();
this.replies.addAll(replies);
return this;
* @param reply
* The reply to add
*/
- public void addReply(PostReply reply) {
+ public void addReply(@Nonnull PostReply reply) {
if (reply.getSone().equals(this)) {
replies.add(reply);
}
* @param reply
* The reply to remove
*/
- public void removeReply(PostReply reply) {
+ public void removeReply(@Nonnull PostReply reply) {
if (reply.getSone().equals(this)) {
replies.remove(reply);
}
*
* @return All liked postsā IDs
*/
+ @Nonnull
public Set<String> getLikedPostIds() {
return Collections.unmodifiableSet(likedPostIds);
}
* All liked postsā IDs
* @return This Sone (for method chaining)
*/
- public Sone setLikePostIds(Set<String> likedPostIds) {
+ @Nonnull
+ public Sone setLikePostIds(@Nonnull Set<String> likedPostIds) {
this.likedPostIds.clear();
this.likedPostIds.addAll(likedPostIds);
return this;
* @return {@code true} if this Sone likes the given post, {@code false}
* otherwise
*/
- public boolean isLikedPostId(String postId) {
+ public boolean isLikedPostId(@Nonnull String postId) {
return likedPostIds.contains(postId);
}
* The ID of the post
* @return This Sone (for method chaining)
*/
- public Sone addLikedPostId(String postId) {
+ @Nonnull
+ public Sone addLikedPostId(@Nonnull String postId) {
likedPostIds.add(postId);
return this;
}
*
* @param postId
* The ID of the post
- * @return This Sone (for method chaining)
*/
- public Sone removeLikedPostId(String postId) {
+ public void removeLikedPostId(@Nonnull String postId) {
likedPostIds.remove(postId);
- return this;
}
/**
*
* @return All liked repliesā IDs
*/
+ @Nonnull
public Set<String> getLikedReplyIds() {
return Collections.unmodifiableSet(likedReplyIds);
}
* All liked repliesā IDs
* @return This Sone (for method chaining)
*/
- public Sone setLikeReplyIds(Set<String> likedReplyIds) {
+ @Nonnull
+ public Sone setLikeReplyIds(@Nonnull Set<String> likedReplyIds) {
this.likedReplyIds.clear();
this.likedReplyIds.addAll(likedReplyIds);
return this;
* @return {@code true} if this Sone likes the given reply, {@code false}
* otherwise
*/
- public boolean isLikedReplyId(String replyId) {
+ public boolean isLikedReplyId(@Nonnull String replyId) {
return likedReplyIds.contains(replyId);
}
* The ID of the reply
* @return This Sone (for method chaining)
*/
- public Sone addLikedReplyId(String replyId) {
+ @Nonnull
+ public Sone addLikedReplyId(@Nonnull String replyId) {
likedReplyIds.add(replyId);
return this;
}
*
* @param replyId
* The ID of the reply
- * @return This Sone (for method chaining)
*/
- public Sone removeLikedReplyId(String replyId) {
+ public void removeLikedReplyId(@Nonnull String replyId) {
likedReplyIds.remove(replyId);
- return this;
}
/**
*
* @return The root album of this Sone
*/
+ @Nonnull
public Album getRootAlbum() {
return rootAlbum;
}
*
* @return The options of this Sone
*/
+ @Nonnull
public SoneOptions getOptions() {
return options;
}
* The options of this Sone
*/
/* TODO - remove this method again, maybe add an option provider */
- public void setOptions(SoneOptions options) {
+ public void setOptions(@Nonnull SoneOptions options) {
this.options = options;
}
@Override
public synchronized String getFingerprint() {
Hasher hash = Hashing.sha256().newHasher();
- hash.putString(profile.getFingerprint());
+ hash.putString(profile.getFingerprint(), UTF_8);
- hash.putString("Posts(");
+ hash.putString("Posts(", UTF_8);
for (Post post : getPosts()) {
- hash.putString("Post(").putString(post.getId()).putString(")");
+ hash.putString("Post(", UTF_8).putString(post.getId(), UTF_8).putString(")", UTF_8);
}
- hash.putString(")");
+ hash.putString(")", UTF_8);
- List<PostReply> replies = new ArrayList<PostReply>(getReplies());
+ List<PostReply> replies = new ArrayList<>(getReplies());
Collections.sort(replies, Reply.TIME_COMPARATOR);
- hash.putString("Replies(");
+ hash.putString("Replies(", UTF_8);
for (PostReply reply : replies) {
- hash.putString("Reply(").putString(reply.getId()).putString(")");
+ hash.putString("Reply(", UTF_8).putString(reply.getId(), UTF_8).putString(")", UTF_8);
}
- hash.putString(")");
+ hash.putString(")", UTF_8);
- List<String> likedPostIds = new ArrayList<String>(getLikedPostIds());
+ List<String> likedPostIds = new ArrayList<>(getLikedPostIds());
Collections.sort(likedPostIds);
- hash.putString("LikedPosts(");
+ hash.putString("LikedPosts(", UTF_8);
for (String likedPostId : likedPostIds) {
- hash.putString("Post(").putString(likedPostId).putString(")");
+ hash.putString("Post(", UTF_8).putString(likedPostId, UTF_8).putString(")", UTF_8);
}
- hash.putString(")");
+ hash.putString(")", UTF_8);
- List<String> likedReplyIds = new ArrayList<String>(getLikedReplyIds());
+ List<String> likedReplyIds = new ArrayList<>(getLikedReplyIds());
Collections.sort(likedReplyIds);
- hash.putString("LikedReplies(");
+ hash.putString("LikedReplies(", UTF_8);
for (String likedReplyId : likedReplyIds) {
- hash.putString("Reply(").putString(likedReplyId).putString(")");
+ hash.putString("Reply(", UTF_8).putString(likedReplyId, UTF_8).putString(")", UTF_8);
}
- hash.putString(")");
+ hash.putString(")", UTF_8);
- hash.putString("Albums(");
+ hash.putString("Albums(", UTF_8);
for (Album album : rootAlbum.getAlbums()) {
if (!Album.NOT_EMPTY.apply(album)) {
continue;
}
- hash.putString(album.getFingerprint());
+ hash.putString(album.getFingerprint(), UTF_8);
}
- hash.putString(")");
+ hash.putString(")", UTF_8);
return hash.hash().toString();
}