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.filter.Filter;
import net.pterodactylus.util.logging.Logging;
+import net.pterodactylus.util.validation.Validation;
import freenet.keys.FreenetURI;
/**
};
+ /**
+ * 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());
+ }
+ };
+
/** Filter to remove Sones that have not been downloaded. */
public static final Filter<Sone> EMPTY_SONE_FILTER = new Filter<Sone>() {
}
};
+ /** Filter that matches all {@link Core#isLocalSone(Sone) local Sones}. */
+ public static final Filter<Sone> LOCAL_SONE_FILTER = new Filter<Sone>() {
+
+ @Override
+ public boolean filterObject(Sone sone) {
+ return sone.getIdentity() instanceof OwnIdentity;
+ }
+
+ };
+
/** The logger. */
private static final Logger logger = Logging.getLogger(Sone.class);
/** The IDs of all liked replies. */
private final Set<String> likedReplyIds = Collections.synchronizedSet(new HashSet<String>());
+ /** The albums of this Sone. */
+ private final List<Album> albums = Collections.synchronizedList(new ArrayList<Album>());
+
/** Sone-specific options. */
private final Options options = new Options();
*/
public void setLatestEdition(long latestEdition) {
if (!(latestEdition > this.latestEdition)) {
- logger.log(Level.INFO, "New latest edition %d is not greater than current latest edition %d!", new Object[] { latestEdition, this.latestEdition });
+ logger.log(Level.FINE, "New latest edition %d is not greater than current latest edition %d!", new Object[] { latestEdition, this.latestEdition });
return;
}
this.latestEdition = latestEdition;
}
/**
+ * Returns the albums of this Sone.
+ *
+ * @return The albums of this Sone
+ */
+ public List<Album> getAlbums() {
+ return Collections.unmodifiableList(albums);
+ }
+
+ /**
+ * Adds an album to this Sone.
+ *
+ * @param album
+ * The album to add
+ */
+ public synchronized void addAlbum(Album album) {
+ Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).check();
+ albums.add(album);
+ }
+
+ /**
+ * Sets the albums of this Sone.
+ *
+ * @param albums
+ * The albums of this Sone
+ */
+ public synchronized void setAlbums(Collection<? extends Album> albums) {
+ Validation.begin().isNotNull("Albums", albums).check();
+ this.albums.clear();
+ for (Album album : albums) {
+ addAlbum(album);
+ }
+ }
+
+ /**
+ * Removes an album from this Sone.
+ *
+ * @param album
+ * The album to remove
+ */
+ public synchronized void removeAlbum(Album album) {
+ Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).check();
+ albums.remove(album);
+ }
+
+ /**
* Returns Sone-specific options.
*
* @return The options of this Sone
}
fingerprint.append(')');
+ fingerprint.append("Albums(");
+ for (Album album : albums) {
+ fingerprint.append(album.getFingerprint());
+ }
+ fingerprint.append(')');
+
return fingerprint.toString();
}
//
+ // STATIC METHODS
+ //
+
+ /**
+ * Flattens the given top-level albums so that the resulting list contains
+ * parent albums before child albums and the resulting list can be parsed in
+ * a single pass.
+ *
+ * @param albums
+ * The albums to flatten
+ * @return The flattened albums
+ */
+ public static List<Album> flattenAlbums(Collection<? extends Album> albums) {
+ List<Album> flatAlbums = new ArrayList<Album>();
+ flatAlbums.addAll(albums);
+ int lastAlbumIndex = 0;
+ while (lastAlbumIndex < flatAlbums.size()) {
+ int previousAlbumCount = flatAlbums.size();
+ for (Album album : new ArrayList<Album>(flatAlbums.subList(lastAlbumIndex, flatAlbums.size()))) {
+ flatAlbums.addAll(album.getAlbums());
+ }
+ lastAlbumIndex = previousAlbumCount;
+ }
+ return flatAlbums;
+ }
+
+ //
// INTERFACE Comparable<Sone>
//