/*
* Sone - Sone.java - Copyright © 2010–2016 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 <http://www.gnu.org/licenses/>.
*/
package net.pterodactylus.sone.data;
import static com.google.common.collect.FluentIterable.from;
import static java.util.Arrays.asList;
import static net.pterodactylus.sone.data.Album.FLATTENER;
import static net.pterodactylus.sone.data.Album.IMAGES;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.pterodactylus.sone.freenet.wot.Identity;
import net.pterodactylus.sone.freenet.wot.OwnIdentity;
import net.pterodactylus.sone.template.SoneAccessor;
import freenet.keys.FreenetURI;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.primitives.Ints;
/**
* A Sone defines everything about a user: her profile, her status updates, her
* replies, her likes and dislikes, etc.
*
* @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
public interface Sone extends Identified, Fingerprintable, Comparable<Sone> {
/**
* Enumeration for the possible states of a {@link Sone}.
*
* @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
public enum SoneStatus {
/** The Sone is unknown, i.e. not yet downloaded. */
unknown,
/** 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 possible values for the “show custom avatars” option.
*
* @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
public static enum ShowCustomAvatars {
/** Never show custom avatars. */
NEVER,
/** Only show custom avatars of followed Sones. */
FOLLOWED,
/** Only show custom avatars of Sones you manually trust. */
MANUALLY_TRUSTED,
/** Only show custom avatars of automatically trusted Sones. */
TRUSTED,
/** Always show custom avatars. */
ALWAYS,
}
/** comparator that sorts Sones by their nice name. */
public static final Comparator<Sone> NICE_NAME_COMPARATOR = new Comparator<Sone>() {
@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());
}
};
/** Comparator that sorts Sones by last activity (least recent active first). */
public static final Comparator<Sone> LAST_ACTIVITY_COMPARATOR = new Comparator<Sone>() {
@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<Sone> POST_COUNT_COMPARATOR = new Comparator<Sone>() {
/**
* {@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<Sone> IMAGE_COUNT_COMPARATOR = new Comparator<Sone>() {
/**
* {@inheritDoc}
*/
@Override
public int compare(Sone leftSone, Sone rightSone) {
int rightSoneImageCount = from(asList(rightSone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES).size();
int leftSoneImageCount = from(asList(leftSone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES).size();
/* sort descending. */
return Ints.compare(rightSoneImageCount, leftSoneImageCount);
}
};
/** Filter to remove Sones that have not been downloaded. */
public static final Predicate<Sone> EMPTY_SONE_FILTER = new Predicate<Sone>() {
@Override
public boolean apply(Sone sone) {
return (sone != null) && (sone.getTime() != 0);
}
};
/** Filter that matches all {@link Sone#isLocal() local Sones}. */
public static final Predicate<Sone> LOCAL_SONE_FILTER = new Predicate<Sone>() {
@Override
public boolean apply(Sone sone) {
return (sone != null) && (sone.getIdentity() instanceof OwnIdentity);
}
};
/** Filter that matches Sones that have at least one album. */
public static final Predicate<Sone> HAS_ALBUM_FILTER = new Predicate<Sone>() {
@Override
public boolean apply(Sone sone) {
return (sone != null) && !sone.getRootAlbum().getAlbums().isEmpty();
}
};
public static final Function<Sone, List<Album>> toAllAlbums = new Function<Sone, List<Album>>() {
@Override
public List<Album> apply(@Nullable Sone sone) {
return (sone == null) ? Collections.<Album>emptyList() : FLATTENER.apply(
sone.getRootAlbum());
}
};
public static final Function<Sone, List<Image>> toAllImages = new Function<Sone, List<Image>>() {
@Override
public List<Image> apply(@Nullable Sone sone) {
return (sone == null) ? Collections.<Image>emptyList() :
from(FLATTENER.apply(sone.getRootAlbum()))
.transformAndConcat(IMAGES).toList();
}
};
/**
* Returns the identity of this Sone.
*
* @return The identity of this Sone
*/
Identity getIdentity();
/**
* Returns the name of this Sone.
*
* @return The name of this Sone
*/
String getName();
/**
* Returns whether this Sone is a local Sone.
*
* @return {@code true} if this Sone is a local Sone, {@code false} otherwise
*/
boolean isLocal();
/**
* Returns the request URI of this Sone.
*
* @return The request URI of this Sone
*/
FreenetURI getRequestUri();
/**
* Returns the insert URI of this Sone.
*
* @return The insert URI of this Sone
*/
FreenetURI getInsertUri();
/**
* Returns the latest edition of this Sone.
*
* @return The latest edition of this Sone
*/
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
*/
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)
*/
long getTime();
/**
* Sets the time of the last inserted update of this Sone.
*
* @param time
* The time of the update (in milliseconds since Jan 1, 1970 UTC)
* @return This Sone (for method chaining)
*/
Sone setTime(long time);
/**
* Returns the status of this Sone.
*
* @return The status of this Sone
*/
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}
*/
Sone setStatus(SoneStatus status);
/**
* 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
*/
Profile getProfile();
/**
* 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
*/
void setProfile(Profile profile);
/**
* Returns the client used by this Sone.
*
* @return The client used by this Sone, or {@code null}
*/
Client getClient();
/**
* Sets the client used by this Sone.
*
* @param client
* The client used by this Sone, or {@code null}
* @return This Sone (for method chaining)
*/
Sone setClient(Client client);
/**
* Returns whether this Sone is known.
*
* @return {@code true} if this Sone is known, {@code false} otherwise
*/
boolean isKnown();
/**
* Sets whether this Sone is known.
*
* @param known
* {@code true} if this Sone is known, {@code false} otherwise
* @return This Sone
*/
Sone setKnown(boolean known);
/**
* Returns all friend Sones of this Sone.
*
* @return The friend Sones of this Sone
*/
Collection<String> getFriends();
/**
* Returns whether this Sone has the given Sone as a friend Sone.
*
* @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
*/
boolean hasFriend(String friendSoneId);
/**
* Returns the list of posts of this Sone, sorted by time, newest first.
*
* @return All posts of this Sone
*/
List<Post> getPosts();
/**
* Sets all posts of this Sone at once.
*
* @param posts
* The new (and only) posts of this Sone
* @return This Sone (for method chaining)
*/
Sone setPosts(Collection<Post> posts);
/**
* 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
*/
void addPost(Post post);
/**
* Removes the given post from this Sone.
*
* @param post
* The post to remove
*/
void removePost(Post post);
/**
* Returns all replies this Sone made.
*
* @return All replies this Sone made
*/
Set<PostReply> getReplies();
/**
* Sets all replies of this Sone at once.
*
* @param replies
* The new (and only) replies of this Sone
* @return This Sone (for method chaining)
*/
Sone setReplies(Collection<PostReply> 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
*/
void addReply(PostReply reply);
/**
* Removes a reply from this Sone.
*
* @param reply
* The reply to remove
*/
void removeReply(PostReply reply);
/**
* Returns the IDs of all liked posts.
*
* @return All liked posts’ IDs
*/
Set<String> getLikedPostIds();
/**
* Sets the IDs of all liked posts.
*
* @param likedPostIds
* All liked posts’ IDs
* @return This Sone (for method chaining)
*/
Sone setLikePostIds(Set<String> 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
*/
boolean isLikedPostId(String postId);
/**
* Adds the given post ID to the list of posts this Sone likes.
*
* @param postId
* The ID of the post
* @return This Sone (for method chaining)
*/
Sone addLikedPostId(String postId);
/**
* Removes the given post ID from the list of posts this Sone likes.
*
* @param postId
* The ID of the post
* @return This Sone (for method chaining)
*/
Sone removeLikedPostId(String postId);
/**
* Returns the IDs of all liked replies.
*
* @return All liked replies’ IDs
*/
Set<String> getLikedReplyIds();
/**
* Sets the IDs of all liked replies.
*
* @param likedReplyIds
* All liked replies’ IDs
* @return This Sone (for method chaining)
*/
Sone setLikeReplyIds(Set<String> likedReplyIds);
/**
* Checks whether the given reply ID is liked by this Sone.
*
* @param replyId
* The ID of the reply
* @return {@code true} if this Sone likes the given reply, {@code false}
* otherwise
*/
boolean isLikedReplyId(String replyId);
/**
* Adds the given reply ID to the list of replies this Sone likes.
*
* @param replyId
* The ID of the reply
* @return This Sone (for method chaining)
*/
Sone addLikedReplyId(String replyId);
/**
* Removes the given post ID from the list of replies this Sone likes.
*
* @param replyId
* The ID of the reply
* @return This Sone (for method chaining)
*/
Sone removeLikedReplyId(String replyId);
/**
* Returns the root album that contains all visible albums of this Sone.
*
* @return The root album of this Sone
*/
Album getRootAlbum();
/**
* Returns Sone-specific options.
*
* @return The options of this Sone
*/
SoneOptions getOptions();
/**
* Sets the options of this Sone.
*
* @param options
* The options of this Sone
*/
/* TODO - remove this method again, maybe add an option provider */
void setOptions(SoneOptions options);
}