X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fdata%2FSone.java;h=2dd4bc14c8b3b70ca3f027c72323db8402fef00b;hb=b4608e322cfce820634b96de1afedd7d625763bc;hp=21ffd6f6d908f8886b435e1bd9520c6d204aa24a;hpb=44084738faad1c0c2609f332beef51feb148e66b;p=Sone.git diff --git a/src/main/java/net/pterodactylus/sone/data/Sone.java b/src/main/java/net/pterodactylus/sone/data/Sone.java index 21ffd6f..2dd4bc1 100644 --- a/src/main/java/net/pterodactylus/sone/data/Sone.java +++ b/src/main/java/net/pterodactylus/sone/data/Sone.java @@ -27,8 +27,10 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import net.pterodactylus.sone.core.Options; import net.pterodactylus.sone.freenet.wot.Identity; import net.pterodactylus.sone.template.SoneAccessor; +import net.pterodactylus.util.filter.Filter; import net.pterodactylus.util.logging.Logging; import freenet.keys.FreenetURI; @@ -40,7 +42,7 @@ import freenet.keys.FreenetURI; * * @author David ‘Bombe’ Roden */ -public class Sone { +public class Sone implements Fingerprintable, Comparable { /** comparator that sorts Sones by their nice name. */ public static final Comparator NICE_NAME_COMPARATOR = new Comparator() { @@ -56,11 +58,23 @@ public class Sone { }; + /** Filter to remove Sones that have not been downloaded. */ + public static final Filter EMPTY_SONE_FILTER = new Filter() { + + @Override + public boolean filterObject(Sone sone) { + return sone.getTime() != 0; + } + }; + /** The logger. */ private static final Logger logger = Logging.getLogger(Sone.class); + /** The ID of this Sone. */ + private final String id; + /** The identity of this Sone. */ - private final Identity identity; + private Identity identity; /** The URI under which the Sone is stored in Freenet. */ private volatile FreenetURI requestUri; @@ -76,10 +90,13 @@ public class Sone { private volatile long time; /** The profile of this Sone. */ - private volatile Profile profile; + private volatile Profile profile = new Profile(); + + /** The client used by the Sone. */ + private volatile Client client; /** All friend Sones. */ - private final Set friendSones = Collections.synchronizedSet(new HashSet()); + private final Set friendSones = Collections.synchronizedSet(new HashSet()); /** All posts. */ private final Set posts = Collections.synchronizedSet(new HashSet()); @@ -93,17 +110,17 @@ public class Sone { /** The IDs of all liked replies. */ private final Set likedReplyIds = Collections.synchronizedSet(new HashSet()); - /** Modification count. */ - private volatile long modificationCounter = 0; + /** Sone-specific options. */ + private final Options options = new Options(); /** * Creates a new Sone. * - * @param identity - * The identity of the Sone + * @param id + * The ID of the Sone */ - public Sone(Identity identity) { - this.identity = identity; + public Sone(String id) { + this.id = id; } // @@ -116,7 +133,7 @@ public class Sone { * @return The identity of this Sone */ public String getId() { - return identity.getId(); + return id; } /** @@ -129,12 +146,30 @@ public class Sone { } /** + * Sets the identity of this Sone. The {@link Identity#getId() ID} of the + * identity has to match this Sone’s {@link #getId()}. + * + * @param identity + * The identity of this Sone + * @return This Sone (for method chaining) + * @throws IllegalArgumentException + * if the ID of the identity does not match this Sone’s ID + */ + public Sone setIdentity(Identity identity) throws IllegalArgumentException { + if (!identity.getId().equals(id)) { + throw new IllegalArgumentException("Identity’s ID does not match Sone’s ID!"); + } + this.identity = identity; + return this; + } + + /** * Returns the name of this Sone. * * @return The name of this Sone */ public String getName() { - return identity.getNickname(); + return (identity != null) ? identity.getNickname() : null; } /** @@ -143,7 +178,7 @@ public class Sone { * @return The request URI of this Sone */ public FreenetURI getRequestUri() { - return requestUri.setSuggestedEdition(latestEdition); + return (requestUri != null) ? requestUri.setSuggestedEdition(latestEdition) : null; } /** @@ -155,14 +190,13 @@ public class Sone { */ public Sone setRequestUri(FreenetURI requestUri) { if (this.requestUri == null) { - this.requestUri = requestUri; + this.requestUri = requestUri.setKeyType("USK").setDocName("Sone").setMetaString(new String[0]); return this; } if (!this.requestUri.equalsKeypair(requestUri)) { logger.log(Level.WARNING, "Request URI %s tried to overwrite %s!", new Object[] { requestUri, this.requestUri }); return this; } - setLatestEdition(requestUri.getEdition()); return this; } @@ -172,7 +206,7 @@ public class Sone { * @return The insert URI of this Sone */ public FreenetURI getInsertUri() { - return insertUri.setSuggestedEdition(latestEdition); + return (insertUri != null) ? insertUri.setSuggestedEdition(latestEdition) : null; } /** @@ -184,14 +218,13 @@ public class Sone { */ public Sone setInsertUri(FreenetURI insertUri) { if (this.insertUri == null) { - this.insertUri = insertUri; + this.insertUri = insertUri.setKeyType("USK").setDocName("Sone").setMetaString(new String[0]); return this; } if (!this.insertUri.equalsKeypair(insertUri)) { logger.log(Level.WARNING, "Request URI %s tried to overwrite %s!", new Object[] { insertUri, this.insertUri }); return this; } - setLatestEdition(insertUri.getEdition()); return this; } @@ -248,7 +281,7 @@ public class Sone { * * @return A copy of the profile */ - public Profile getProfile() { + public synchronized Profile getProfile() { return new Profile(profile); } @@ -262,7 +295,27 @@ public class Sone { */ public synchronized void setProfile(Profile profile) { this.profile = new Profile(profile); - modificationCounter++; + } + + /** + * Returns the client used by this Sone. + * + * @return The client used by this Sone, or {@code null} + */ + public Client getClient() { + return client; + } + + /** + * Sets the client used by this Sone. + * + * @param client + * The client used by this Sone, or {@code null} + * @return This Sone (for method chaining) + */ + public Sone setClient(Client client) { + this.client = client; + return this; } /** @@ -270,19 +323,8 @@ public class Sone { * * @return The friend Sones of this Sone */ - public List getFriends() { - List friends = new ArrayList(friendSones); - Collections.sort(friends, new Comparator() { - - @Override - public int compare(Sone leftSone, Sone rightSone) { - int diff = SoneAccessor.getNiceName(leftSone).compareToIgnoreCase(SoneAccessor.getNiceName(rightSone)); - if (diff != 0) { - return diff; - } - return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, rightSone.getTime() - leftSone.getTime())); - } - }); + public List getFriends() { + List friends = new ArrayList(friendSones); return friends; } @@ -293,7 +335,7 @@ public class Sone { * The new (and only) friends of this Sone * @return This Sone (for method chaining) */ - public Sone setFriends(Collection friends) { + public Sone setFriends(Collection friends) { friendSones.clear(); friendSones.addAll(friends); return this; @@ -302,13 +344,13 @@ public class Sone { /** * Returns whether this Sone has the given Sone as a friend Sone. * - * @param friendSone - * The friend Sone to check for + * @param friendSoneId + * The ID of the Sone to check for * @return {@code true} if this Sone has the given Sone as a friend, * {@code false} otherwise */ - public boolean hasFriend(Sone friendSone) { - return friendSones.contains(friendSone); + public boolean hasFriend(String friendSoneId) { + return friendSones.contains(friendSoneId); } /** @@ -318,8 +360,8 @@ public class Sone { * The friend Sone to add * @return This Sone (for method chaining) */ - public Sone addFriend(Sone friendSone) { - if (!friendSone.equals(this)) { + public Sone addFriend(String friendSone) { + if (!friendSone.equals(id)) { friendSones.add(friendSone); } return this; @@ -328,12 +370,12 @@ public class Sone { /** * Removes the given Sone as a friend Sone. * - * @param friendSone - * The friend Sone to remove + * @param friendSoneId + * The ID of the friend Sone to remove * @return This Sone (for method chaining) */ - public Sone removeFriend(Sone friendSone) { - friendSones.remove(friendSone); + public Sone removeFriend(String friendSoneId) { + friendSones.remove(friendSoneId); return this; } @@ -343,15 +385,11 @@ public class Sone { * @return All posts of this Sone */ public List getPosts() { - List sortedPosts = new ArrayList(posts); - Collections.sort(sortedPosts, new Comparator() { - - @Override - public int compare(Post leftPost, Post rightPost) { - return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, rightPost.getTime() - leftPost.getTime())); - } - - }); + List sortedPosts; + synchronized (this) { + sortedPosts = new ArrayList(posts); + } + Collections.sort(sortedPosts, Post.TIME_COMPARATOR); return sortedPosts; } @@ -363,9 +401,10 @@ public class Sone { * @return This Sone (for method chaining) */ public synchronized Sone setPosts(Collection posts) { - this.posts.clear(); - this.posts.addAll(posts); - modificationCounter++; + synchronized (this) { + this.posts.clear(); + this.posts.addAll(posts); + } return this; } @@ -379,7 +418,6 @@ public class Sone { public synchronized void addPost(Post post) { if (post.getSone().equals(this) && posts.add(post)) { logger.log(Level.FINEST, "Adding %s to “%s”.", new Object[] { post, getName() }); - modificationCounter++; } } @@ -390,8 +428,8 @@ public class Sone { * The post to remove */ public synchronized void removePost(Post post) { - if (post.getSone().equals(this) && posts.remove(post)) { - modificationCounter++; + if (post.getSone().equals(this)) { + posts.remove(post); } } @@ -400,8 +438,7 @@ public class Sone { * * @return All replies this Sone made */ - public Set getReplies() { - logger.log(Level.FINEST, "Friends of %s: %s", new Object[] { this, friendSones }); + public synchronized Set getReplies() { return Collections.unmodifiableSet(replies); } @@ -415,7 +452,6 @@ public class Sone { public synchronized Sone setReplies(Collection replies) { this.replies.clear(); this.replies.addAll(replies); - modificationCounter++; return this; } @@ -427,8 +463,8 @@ public class Sone { * The reply to add */ public synchronized void addReply(Reply reply) { - if (reply.getSone().equals(this) && replies.add(reply)) { - modificationCounter++; + if (reply.getSone().equals(this)) { + replies.add(reply); } } @@ -439,8 +475,8 @@ public class Sone { * The reply to remove */ public synchronized void removeReply(Reply reply) { - if (reply.getSone().equals(this) && replies.remove(reply)) { - modificationCounter++; + if (reply.getSone().equals(this)) { + replies.remove(reply); } } @@ -463,7 +499,6 @@ public class Sone { public synchronized Sone setLikePostIds(Set likedPostIds) { this.likedPostIds.clear(); this.likedPostIds.addAll(likedPostIds); - modificationCounter++; return this; } @@ -487,9 +522,7 @@ public class Sone { * @return This Sone (for method chaining) */ public synchronized Sone addLikedPostId(String postId) { - if (likedPostIds.add(postId)) { - modificationCounter++; - } + likedPostIds.add(postId); return this; } @@ -501,9 +534,7 @@ public class Sone { * @return This Sone (for method chaining) */ public synchronized Sone removeLikedPostId(String postId) { - if (likedPostIds.remove(postId)) { - modificationCounter++; - } + likedPostIds.remove(postId); return this; } @@ -526,7 +557,6 @@ public class Sone { public synchronized Sone setLikeReplyIds(Set likedReplyIds) { this.likedReplyIds.clear(); this.likedReplyIds.addAll(likedReplyIds); - modificationCounter++; return this; } @@ -550,9 +580,7 @@ public class Sone { * @return This Sone (for method chaining) */ public synchronized Sone addLikedReplyId(String replyId) { - if (likedReplyIds.add(replyId)) { - modificationCounter++; - } + likedReplyIds.add(replyId); return this; } @@ -564,29 +592,74 @@ public class Sone { * @return This Sone (for method chaining) */ public synchronized Sone removeLikedReplyId(String replyId) { - if (likedReplyIds.remove(replyId)) { - modificationCounter++; - } + likedReplyIds.remove(replyId); return this; } /** - * Returns the modification counter. + * Returns Sone-specific options. * - * @return The modification counter + * @return The options of this Sone */ - public synchronized long getModificationCounter() { - return modificationCounter; + public Options getOptions() { + return options; } + // + // FINGERPRINTABLE METHODS + // + /** - * Sets the modification counter. - * - * @param modificationCounter - * The new modification counter + * {@inheritDoc} */ - public synchronized void setModificationCounter(long modificationCounter) { - this.modificationCounter = modificationCounter; + @Override + public synchronized String getFingerprint() { + StringBuilder fingerprint = new StringBuilder(); + fingerprint.append(profile.getFingerprint()); + + fingerprint.append("Posts("); + for (Post post : getPosts()) { + fingerprint.append("Post(").append(post.getId()).append(')'); + } + fingerprint.append(")"); + + List replies = new ArrayList(getReplies()); + Collections.sort(replies, Reply.TIME_COMPARATOR); + fingerprint.append("Replies("); + for (Reply reply : replies) { + fingerprint.append("Reply(").append(reply.getId()).append(')'); + } + fingerprint.append(')'); + + List likedPostIds = new ArrayList(getLikedPostIds()); + Collections.sort(likedPostIds); + fingerprint.append("LikedPosts("); + for (String likedPostId : likedPostIds) { + fingerprint.append("Post(").append(likedPostId).append(')'); + } + fingerprint.append(')'); + + List likedReplyIds = new ArrayList(getLikedReplyIds()); + Collections.sort(likedReplyIds); + fingerprint.append("LikedReplies("); + for (String likedReplyId : likedReplyIds) { + fingerprint.append("Reply(").append(likedReplyId).append(')'); + } + fingerprint.append(')'); + + return fingerprint.toString(); + } + + // + // INTERFACE Comparable + // + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(Sone sone) { + return NICE_NAME_COMPARATOR.compare(this, sone); } // @@ -598,7 +671,7 @@ public class Sone { */ @Override public int hashCode() { - return identity.getId().hashCode(); + return id.hashCode(); } /** @@ -609,7 +682,7 @@ public class Sone { if (!(object instanceof Sone)) { return false; } - return ((Sone) object).identity.getId().equals(identity.getId()); + return ((Sone) object).id.equals(id); } /** @@ -617,7 +690,7 @@ public class Sone { */ @Override public String toString() { - return getClass().getName() + "[identity=" + identity + ",requestUri=" + requestUri + ",insertUri=" + insertUri + ",friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + ")]"; + return getClass().getName() + "[identity=" + identity + ",requestUri=" + requestUri + ",insertUri(" + String.valueOf(insertUri).length() + "),friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + ")]"; } }