X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fdata%2FSone.java;h=28a5afa765fe39110cb5437de407e678fd43a793;hb=c1fd1bc55bd809fd4ee447b2679bb8aafe4e06fc;hp=2e23ed11118472950c26d77b8b93f4a8cfa1613f;hpb=c8f518f638aa16cf37145561b709d28252de213a;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 2e23ed1..28a5afa 100644 --- a/src/main/java/net/pterodactylus/sone/data/Sone.java +++ b/src/main/java/net/pterodactylus/sone/data/Sone.java @@ -1,5 +1,5 @@ /* - * FreenetSone - Sone.java - Copyright © 2010 David Roden + * Sone - Sone.java - Copyright © 2010–2012 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 @@ -17,19 +17,17 @@ package net.pterodactylus.sone.data; -import java.util.ArrayList; import java.util.Collection; -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.sone.core.Core; +import net.pterodactylus.sone.core.Options; +import net.pterodactylus.sone.freenet.wot.Identity; +import net.pterodactylus.sone.freenet.wot.OwnIdentity; import net.pterodactylus.sone.template.SoneAccessor; -import net.pterodactylus.util.logging.Logging; +import net.pterodactylus.util.collection.filter.Filter; import freenet.keys.FreenetURI; /** @@ -40,100 +38,179 @@ import freenet.keys.FreenetURI; * * @author David ‘Bombe’ Roden */ -public class Sone { +public interface Sone extends Fingerprintable, Comparable { - /** The logger. */ - private static final Logger logger = Logging.getLogger(Sone.class); + /** + * Enumeration for the possible states of a {@link Sone}. + * + * @author David ‘Bombe’ Roden + */ + public enum SoneStatus { - /** A GUID for this Sone. */ - private final UUID id; + /** The Sone is unknown, i.e. not yet downloaded. */ + unknown, - /** The name of this Sone. */ - private String name; + /** The Sone is idle, i.e. not being downloaded or inserted. */ + idle, + + /** The Sone is currently being inserted. */ + inserting, + + /** The Sone is currently being downloaded. */ + downloading, + } - /** The URI under which the Sone is stored in Freenet. */ - private FreenetURI requestUri; + /** + * The possible values for the “show custom avatars” option. + * + * @author David ‘Bombe’ Roden + */ + public static enum ShowCustomAvatars { - /** The URI used to insert a new version of this Sone. */ - /* This will be null for remote Sones! */ - private FreenetURI insertUri; + /** Never show custom avatars. */ + NEVER, - /** The time of the last inserted update. */ - private long time; + /** Only show custom avatars of followed Sones. */ + FOLLOWED, - /** The profile of this Sone. */ - private Profile profile; + /** Only show custom avatars of Sones you manually trust. */ + MANUALLY_TRUSTED, - /** All friend Sones. */ - private final Set friendSones = new HashSet(); + /** Only show custom avatars of automatically trusted Sones. */ + TRUSTED, - /** All posts. */ - private final Set posts = new HashSet(); + /** Always show custom avatars. */ + ALWAYS, - /** All replies. */ - private final Set replies = new HashSet(); + } - /** The IDs of all blocked Sones. */ - private final Set blockedSoneIds = new HashSet(); + /** comparator that sorts Sones by their nice name. */ + public static final Comparator NICE_NAME_COMPARATOR = new Comparator() { - /** The IDs of all liked posts. */ - private final Set likedPostIds = new HashSet(); + @Override + public int compare(Sone leftSone, Sone rightSone) { + int diff = SoneAccessor.getNiceName(leftSone).compareToIgnoreCase(SoneAccessor.getNiceName(rightSone)); + if (diff != 0) { + return diff; + } + return leftSone.getId().compareToIgnoreCase(rightSone.getId()); + } - /** Modification count. */ - private volatile long modificationCounter = 0; + }; /** - * Creates a new Sone. - * - * @param id - * The ID of this Sone + * Comparator that sorts Sones by last activity (least recent active first). */ - public Sone(String id) { - this.id = UUID.fromString(id); - } + public static final Comparator LAST_ACTIVITY_COMPARATOR = new Comparator() { + + @Override + public int compare(Sone firstSone, Sone secondSone) { + return (int) Math.min(Integer.MAX_VALUE, Math.max(Integer.MIN_VALUE, secondSone.getTime() - firstSone.getTime())); + } + }; + + /** Comparator that sorts Sones by numbers of posts (descending). */ + public static final Comparator POST_COUNT_COMPARATOR = new Comparator() { + + /** + * {@inheritDoc} + */ + @Override + public int compare(Sone leftSone, Sone rightSone) { + return (leftSone.getPosts().size() != rightSone.getPosts().size()) ? (rightSone.getPosts().size() - leftSone.getPosts().size()) : (rightSone.getReplies().size() - leftSone.getReplies().size()); + } + }; + + /** Comparator that sorts Sones by number of images (descending). */ + public static final Comparator IMAGE_COUNT_COMPARATOR = new Comparator() { + + /** + * {@inheritDoc} + */ + @Override + public int compare(Sone leftSone, Sone rightSone) { + return rightSone.getAllImages().size() - leftSone.getAllImages().size(); + } + }; + + /** 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; + } + }; + + /** Filter that matches all {@link Core#getLocalSones() local Sones}. */ + public static final Filter LOCAL_SONE_FILTER = new Filter() { + + @Override + public boolean filterObject(Sone sone) { + return sone.getIdentity() instanceof OwnIdentity; + } + + }; + + /** Filter that matches Sones that have at least one album. */ + public static final Filter HAS_ALBUM_FILTER = new Filter() { + + @Override + public boolean filterObject(Sone sone) { + return !sone.getAlbums().isEmpty(); + } + }; // // ACCESSORS // /** - * Returns the ID of this Sone. + * Returns the identity of this Sone. * - * @return The ID of this Sone + * @return The identity of this Sone */ - public String getId() { - return id.toString(); - } + public String getId(); /** - * Returns the name of this Sone. + * Returns the identity of this Sone. * - * @return The name of this Sone + * @return The identity of this Sone */ - public String getName() { - return name; - } + public Identity getIdentity(); /** - * Sets the name of this Sone. + * Sets the identity of this Sone. The {@link Identity#getId() ID} of the + * identity has to match this Sone’s {@link #getId()}. * - * @param name - * The name of this Sone - * @return This sone (for method chaining) + * @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 setName(String name) { - this.name = name; - return this; - } + public Sone setIdentity(Identity identity) throws IllegalArgumentException; + + /** + * Returns whether this Sone is local. + * + * @return {@code true} if this Sone is local, {@code false} otherwise + */ + public boolean isLocal(); + + /** + * Returns the name of this Sone. + * + * @return The name of this Sone + */ + public String getName(); /** * Returns the request URI of this Sone. * * @return The request URI of this Sone */ - public FreenetURI getRequestUri() { - return requestUri; - } + public FreenetURI getRequestUri(); /** * Sets the request URI of this Sone. @@ -142,19 +219,14 @@ public class Sone { * The request URI of this Sone * @return This Sone (for method chaining) */ - public Sone setRequestUri(FreenetURI requestUri) { - this.requestUri = requestUri; - return this; - } + public Sone setRequestUri(FreenetURI requestUri); /** * Returns the insert URI of this Sone. * * @return The insert URI of this Sone */ - public FreenetURI getInsertUri() { - return insertUri; - } + public FreenetURI getInsertUri(); /** * Sets the insert URI of this Sone. @@ -163,19 +235,31 @@ public class Sone { * The insert URI of this Sone * @return This Sone (for method chaining) */ - public Sone setInsertUri(FreenetURI insertUri) { - this.insertUri = insertUri; - return this; - } + public Sone setInsertUri(FreenetURI insertUri); + + /** + * Returns the latest edition of this Sone. + * + * @return The latest edition of this Sone + */ + public long getLatestEdition(); + + /** + * Sets the latest edition of this Sone. If the given latest edition is not + * greater than the current latest edition, the latest edition of this Sone + * is not changed. + * + * @param latestEdition + * The latest edition of this Sone + */ + public void setLatestEdition(long latestEdition); /** * Return the time of the last inserted update of this Sone. * * @return The time of the update (in milliseconds since Jan 1, 1970 UTC) */ - public long getTime() { - return time; - } + public long getTime(); /** * Sets the time of the last inserted update of this Sone. @@ -184,10 +268,25 @@ public class Sone { * The time of the update (in milliseconds since Jan 1, 1970 UTC) * @return This Sone (for method chaining) */ - public Sone setTime(long time) { - this.time = time; - return this; - } + public Sone setTime(long time); + + /** + * Returns the status of this Sone. + * + * @return The status of this Sone + */ + public SoneStatus getStatus(); + + /** + * Sets the new status of this Sone. + * + * @param status + * The new status of this Sone + * @return This Sone + * @throws IllegalArgumentException + * if {@code status} is {@code null} + */ + public Sone setStatus(SoneStatus status); /** * Returns a copy of the profile. If you want to update values in the @@ -196,9 +295,7 @@ public class Sone { * * @return A copy of the profile */ - public Profile getProfile() { - return new Profile(profile); - } + public Profile getProfile(); /** * Sets the profile of this Sone. A copy of the given profile is stored so @@ -208,56 +305,56 @@ public class Sone { * @param profile * The profile to set */ - public synchronized void setProfile(Profile profile) { - this.profile = new Profile(profile); - modificationCounter++; - } + public void setProfile(Profile profile); /** - * Returns all friend Sones of this Sone. + * Returns the client used by this Sone. * - * @return The friend Sones of this Sone + * @return The client used by this Sone, or {@code null} */ - 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).compareTo(SoneAccessor.getNiceName(rightSone)); - if (diff != 0) { - return diff; - } - return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, rightSone.getTime() - leftSone.getTime())); - } - }); - return friends; - } + public Client getClient(); /** - * Sets all friends of this Sone at once. + * Sets the client used by this Sone. * - * @param friends - * The new (and only) friends of this Sone + * @param client + * The client used by this Sone, or {@code null} * @return This Sone (for method chaining) */ - public Sone setFriends(Collection friends) { - friendSones.clear(); - friendSones.addAll(friends); - return this; - } + public Sone setClient(Client client); + + /** + * Returns whether this Sone is known. + * + * @return {@code true} if this Sone is known, {@code false} otherwise + */ + public boolean isKnown(); + + /** + * Sets whether this Sone is known. + * + * @param known + * {@code true} if this Sone is known, {@code false} otherwise + * @return This Sone + */ + public Sone setKnown(boolean known); + + /** + * Returns all friend Sones of this Sone. + * + * @return The friend Sones of this Sone + */ + public Collection getFriends(); /** * 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); /** * Adds the given Sone as a friend Sone. @@ -266,42 +363,23 @@ public class Sone { * The friend Sone to add * @return This Sone (for method chaining) */ - public Sone addFriend(Sone friendSone) { - if (!friendSone.equals(this)) { - friendSones.add(friendSone); - } - return this; - } + public Sone addFriend(String friendSone); /** * 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); - return this; - } + public Sone removeFriend(String friendSoneId); /** * 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; - } + public List getPosts(); /** * Sets all posts of this Sone at once. @@ -310,12 +388,7 @@ public class Sone { * The new (and only) posts of this Sone * @return This Sone (for method chaining) */ - public synchronized Sone setPosts(Collection posts) { - this.posts.clear(); - this.posts.addAll(posts); - modificationCounter++; - return this; - } + public Sone setPosts(Collection posts); /** * Adds the given post to this Sone. The post will not be added if its @@ -324,12 +397,7 @@ public class 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++; - } - } + public void addPost(Post post); /** * Removes the given post from this Sone. @@ -337,21 +405,14 @@ public class Sone { * @param post * The post to remove */ - public synchronized void removePost(Post post) { - if (post.getSone().equals(this) && posts.remove(post)) { - modificationCounter++; - } - } + public void removePost(Post post); /** * Returns all replies this Sone made. * * @return All replies this Sone made */ - public Set getReplies() { - logger.log(Level.FINEST, "Friends of %s: %s", new Object[] { this, friendSones }); - return Collections.unmodifiableSet(replies); - } + public Set getReplies(); /** * Sets all replies of this Sone at once. @@ -360,12 +421,7 @@ public class Sone { * The new (and only) replies of this Sone * @return This Sone (for method chaining) */ - public synchronized Sone setReplies(Collection replies) { - this.replies.clear(); - this.replies.addAll(replies); - modificationCounter++; - return this; - } + public Sone setReplies(Collection replies); /** * Adds a reply to this Sone. If the given reply was not made by this Sone, @@ -374,11 +430,7 @@ public class Sone { * @param reply * The reply to add */ - public synchronized void addReply(Reply reply) { - if (reply.getSone().equals(this) && replies.add(reply)) { - modificationCounter++; - } - } + public void addReply(PostReply reply); /** * Removes a reply from this Sone. @@ -386,184 +438,171 @@ public class Sone { * @param reply * The reply to remove */ - public synchronized void removeReply(Reply reply) { - if (reply.getSone().equals(this) && replies.remove(reply)) { - modificationCounter++; - } - } + public void removeReply(PostReply reply); /** - * Returns the IDs of all blocked Sones. These Sones will not propagated - * using the “known Sones” mechanism. + * Returns the IDs of all liked posts. * - * @return The IDs of all blocked Sones + * @return All liked posts’ IDs */ - public Set getBlockedSoneIds() { - return Collections.unmodifiableSet(blockedSoneIds); - } + public Set getLikedPostIds(); /** - * Returns whether the given Sone ID is blocked. + * Sets the IDs of all liked posts. * - * @param soneId - * The Sone ID to check - * @return {@code true} if the given Sone ID is blocked, {@code false} + * @param likedPostIds + * All liked posts’ IDs + * @return This Sone (for method chaining) + */ + public Sone setLikePostIds(Set likedPostIds); + + /** + * Checks whether the given post ID is liked by this Sone. + * + * @param postId + * The ID of the post + * @return {@code true} if this Sone likes the given post, {@code false} * otherwise */ - public boolean isSoneBlocked(String soneId) { - return blockedSoneIds.contains(soneId); - } + public boolean isLikedPostId(String postId); /** - * Adds the given ID to the list of blocked IDs. + * Adds the given post ID to the list of posts this Sone likes. * - * @param soneId - * The Sone ID to block + * @param postId + * The ID of the post + * @return This Sone (for method chaining) */ - public synchronized void addBlockedSoneId(String soneId) { - if (blockedSoneIds.add(soneId)) { - modificationCounter++; - } - } + public Sone addLikedPostId(String postId); /** - * Removes the given ID from the list of blocked IDs. + * Removes the given post ID from the list of posts this Sone likes. * - * @param soneId - * The Sone ID to unblock + * @param postId + * The ID of the post + * @return This Sone (for method chaining) */ - public synchronized void removeBlockedSoneId(String soneId) { - if (blockedSoneIds.remove(soneId)) { - modificationCounter++; - } - } + public Sone removeLikedPostId(String postId); /** - * Returns the IDs of all liked posts. + * Returns the IDs of all liked replies. * - * @return All liked posts’ IDs + * @return All liked replies’ IDs */ - public Set getLikedPostIds() { - return Collections.unmodifiableSet(likedPostIds); - } + public Set getLikedReplyIds(); /** - * Sets the IDs of all liked posts. + * Sets the IDs of all liked replies. * - * @param likedPostIds - * All liked posts’ IDs + * @param likedReplyIds + * All liked replies’ IDs * @return This Sone (for method chaining) */ - public synchronized Sone setLikePostIds(Set likedPostIds) { - this.likedPostIds.clear(); - this.likedPostIds.addAll(likedPostIds); - modificationCounter++; - return this; - } + public Sone setLikeReplyIds(Set likedReplyIds); /** - * Checks whether the given post ID is liked by this Sone. + * Checks whether the given reply ID is liked by this Sone. * - * @param postId - * The ID of the post - * @return {@code true} if this Sone likes the given post, {@code false} + * @param replyId + * The ID of the reply + * @return {@code true} if this Sone likes the given reply, {@code false} * otherwise */ - public boolean isLikedPostId(String postId) { - return likedPostIds.contains(postId); - } + public boolean isLikedReplyId(String replyId); /** - * Adds the given post ID to the list of posts this Sone likes. + * Adds the given reply ID to the list of replies this Sone likes. * - * @param postId - * The ID of the post + * @param replyId + * The ID of the reply * @return This Sone (for method chaining) */ - public synchronized Sone addLikedPostId(String postId) { - if (likedPostIds.add(postId)) { - modificationCounter++; - } - return this; - } + public Sone addLikedReplyId(String replyId); /** - * Removes the given post ID from the list of posts this Sone likes. + * Removes the given post ID from the list of replies this Sone likes. * - * @param postId - * The ID of the post + * @param replyId + * The ID of the reply * @return This Sone (for method chaining) */ - public synchronized Sone removeLikedPostId(String postId) { - if (likedPostIds.remove(postId)) { - modificationCounter++; - } - return this; - } + public Sone removeLikedReplyId(String replyId); /** - * Returns the modification counter. + * Returns the albums of this Sone. * - * @return The modification counter + * @return The albums of this Sone */ - public synchronized long getModificationCounter() { - return modificationCounter; - } + public List getAlbums(); /** - * Sets the modification counter. + * Returns a flattened list of all albums of this Sone. The resulting list + * contains parent albums before child albums so that the resulting list can + * be parsed in a single pass. * - * @param modificationCounter - * The new modification counter + * @return The flattened albums */ - public synchronized void setModificationCounter(long modificationCounter) { - this.modificationCounter = modificationCounter; - } + public List getAllAlbums(); /** - * Updates the suggested edition in both the request URI and the insert URI. + * Returns all images of a Sone. Images of a album are inserted into this + * list before images of all child albums. * - * @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); - if (this.insertUri != null) { - this.insertUri = this.insertUri.setSuggestedEdition(latestEdition); - } - } + * @return The list of all images + */ + public List getAllImages(); - // - // OBJECT METHODS - // + /** + * Adds an album to this Sone. + * + * @param album + * The album to add + */ + public void addAlbum(Album album); /** - * {@inheritDoc} + * Sets the albums of this Sone. + * + * @param albums + * The albums of this Sone */ - @Override - public int hashCode() { - return id.hashCode(); - } + public void setAlbums(Collection albums); /** - * {@inheritDoc} + * Removes an album from this Sone. + * + * @param album + * The album to remove */ - @Override - public boolean equals(Object object) { - if (!(object instanceof Sone)) { - return false; - } - return ((Sone) object).id.equals(id); - } + public void removeAlbum(Album album); /** - * {@inheritDoc} + * Moves the given album up in this album’s albums. If the album is already + * the first album, nothing happens. + * + * @param album + * The album to move up + * @return The album that the given album swapped the place with, or + * null if the album did not change its place */ - @Override - public String toString() { - return getClass().getName() + "[id=" + id + ",name=" + name + ",requestUri=" + requestUri + ",insertUri=" + insertUri + ",friends(" + friendSones.size() + "),posts(" + posts.size() + "),replies(" + replies.size() + ")]"; - } + public Album moveAlbumUp(Album album); + + /** + * Moves the given album down in this album’s albums. If the album is + * already the last album, nothing happens. + * + * @param album + * The album to move down + * @return The album that the given album swapped the place with, or + * null if the album did not change its place + */ + public Album moveAlbumDown(Album album); + + /** + * Returns Sone-specific options. + * + * @return The options of this Sone + */ + public Options getOptions(); }