X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fdata%2FSone.java;h=7041289b90e3ca45e91cbd9ba8337c4aa98bb801;hb=78cd820b392069def4640d45497e4097ef031d53;hp=5efcc067d07a2e5c94e1f6a0f9827ab9f879e0da;hpb=1c3d65453e87eb0ad558c079f9616684caf8e969;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 5efcc06..7041289 100644 --- a/src/main/java/net/pterodactylus/sone/data/Sone.java +++ b/src/main/java/net/pterodactylus/sone/data/Sone.java @@ -17,42 +17,89 @@ package net.pterodactylus.sone.data; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.pterodactylus.util.logging.Logging; import freenet.keys.FreenetURI; /** - * A Sone defines everything about a user: the {@link User} itself, her profile, - * her status updates. + * A Sone defines everything about a user: her profile, her status updates, her + * replies, her likes and dislikes, etc. + *

+ * Operations that modify the Sone need to synchronize on the Sone in question. * * @author David ‘Bombe’ Roden */ public class Sone { + /** The logger. */ + private static final Logger logger = Logging.getLogger(Sone.class); + + /** A GUID for this Sone. */ + private final UUID id; + + /** The name of this Sone. */ + private final String name; + /** The URI under which the Sone is stored in Freenet. */ - private final FreenetURI requestUri; + private FreenetURI requestUri; /** The URI used to insert a new version of this Sone. */ /* This will be null for remote Sones! */ - private final FreenetURI insertUri; + private FreenetURI insertUri; + + /** The profile of this Sone. */ + private Profile profile; + + /** All friend Sones. */ + private final Set friendSones = new HashSet(); + + /** All posts. */ + private final List posts = new ArrayList(); + + /** All replies. */ + private final Set replies = new HashSet(); + + /** Modification count. */ + private volatile long modificationCounter = 0; /** * Creates a new Sone. * + * @param id + * The ID of this Sone + * @param name + * The name of the Sone * @param requestUri * The request URI of the Sone */ - public Sone(FreenetURI requestUri) { - this(requestUri, null); + public Sone(UUID id, String name, FreenetURI requestUri) { + this(id, name, requestUri, null); } /** * Creates a new Sone. * + * @param id + * The ID of this Sone + * @param name + * The name of the Sone * @param requestUri * The request URI of the Sone * @param insertUri * The insert URI of the Sone */ - public Sone(FreenetURI requestUri, FreenetURI insertUri) { + public Sone(UUID id, String name, FreenetURI requestUri, FreenetURI insertUri) { + this.id = id; + this.name = name; this.requestUri = requestUri; this.insertUri = insertUri; } @@ -62,11 +109,29 @@ public class Sone { // /** + * Returns the ID of this Sone. + * + * @return The ID of this Sone + */ + public String getId() { + return id.toString(); + } + + /** + * Returns the name of this Sone. + * + * @return The name of this Sone + */ + public String getName() { + return name; + } + + /** * Returns the request URI of this Sone. * * @return The request URI of this Sone */ - public FreenetURI requestUri() { + public FreenetURI getRequestUri() { return requestUri; } @@ -75,8 +140,222 @@ public class Sone { * * @return The insert URI of this Sone */ - public FreenetURI insertUri() { + public FreenetURI getInsertUri() { return insertUri; } + /** + * Returns a copy of the profile. If you want to update values in the + * profile of this Sone, update the values in the returned {@link Profile} + * and use {@link #setProfile(Profile)} to change the profile in this Sone. + * + * @return A copy of the profile + */ + public Profile getProfile() { + return new Profile(profile); + } + + /** + * Sets the profile of this Sone. A copy of the given profile is stored so + * that subsequent modifications of the given profile are not reflected in + * this Sone! + * + * @param profile + * The profile to set + */ + public synchronized void setProfile(Profile profile) { + this.profile = new Profile(profile); + modificationCounter++; + } + + /** + * Returns all friend Sones of this Sone. + * + * @return The friend Sones of this Sone + */ + public Set getFriends() { + return Collections.unmodifiableSet(friendSones); + } + + /** + * Returns whether this Sone has the given Sone as a friend Sone. + * + * @param friendSone + * The friend 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); + } + + /** + * Adds the given Sone as a friend Sone. + * + * @param friendSone + * The friend Sone to add + * @return This Sone (for method chaining) + */ + public synchronized Sone addFriend(Sone friendSone) { + if (friendSones.add(friendSone)) { + modificationCounter++; + } + return this; + } + + /** + * Removes the given Sone as a friend Sone. + * + * @param friendSone + * The friend Sone to remove + * @return This Sone (for method chaining) + */ + public synchronized Sone removeFriend(Sone friendSone) { + if (friendSones.remove(friendSone)) { + modificationCounter++; + } + return this; + } + + /** + * Returns the list of posts of this Sone, sorted by time, newest first. + * + * @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())); + } + + }); + return sortedPosts; + } + + /** + * Adds the given post to this Sone. The post will not be added if its + * {@link Post#getSone() Sone} is not this Sone. + * + * @param post + * The post to add + */ + 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++; + } + } + + /** + * Removes the given post from this Sone. + * + * @param post + * The post to remove + */ + public synchronized void removePost(Post post) { + if (post.getSone().equals(this) && posts.remove(post)) { + modificationCounter++; + } + } + + /** + * Returns all replies this Sone made. + * + * @return All replies this Sone made + */ + public Set getReplies() { + return Collections.unmodifiableSet(replies); + } + + /** + * Adds a reply to this Sone. If the given reply was not made by this Sone, + * nothing is added to this Sone. + * + * @param reply + * The reply to add + */ + public synchronized void addReply(Reply reply) { + if (reply.getSone().equals(this) && replies.add(reply)) { + modificationCounter++; + } + } + + /** + * Removes a reply from this Sone. + * + * @param reply + * The reply to remove + */ + public synchronized void removeReply(Reply reply) { + if (reply.getSone().equals(this) && replies.remove(reply)) { + modificationCounter++; + } + } + + /** + * Returns the modification counter. + * + * @return The modification counter + */ + public synchronized long getModificationCounter() { + return modificationCounter; + } + + /** + * Sets the modification counter. + * + * @param modificationCounter + * The new modification counter + */ + public synchronized void setModificationCounter(long modificationCounter) { + this.modificationCounter = modificationCounter; + } + + /** + * Updates the suggested edition in both the request URI and the insert URI. + * + * @param requestUri + * The request URI that resulted from an insert + */ + public void updateUris(FreenetURI requestUri) { + /* TODO - check for the correct URI. */ + long latestEdition = requestUri.getSuggestedEdition(); + this.requestUri = this.requestUri.setSuggestedEdition(latestEdition); + this.insertUri = this.insertUri.setSuggestedEdition(latestEdition); + } + + // + // OBJECT METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return id.hashCode(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object object) { + if (!(object instanceof Sone)) { + return false; + } + return ((Sone) object).id.equals(id); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return getClass().getName() + "[id=" + getId() + ",name=" + getName() + ",requestUri=" + getRequestUri() + ",insertUri=" + getInsertUri() + ",friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + ")]"; + } + }