X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fdata%2FSone.java;h=3aa604e24160a3ff04863f4247f5b440169b7878;hb=67ebd4f4ece65f6e3c32ceaed755fe79323b8be9;hp=a0f87b227d257ade161c5e01ce251da237eb479c;hpb=22788933e4a2b4ee39f298ebcefda5b93b0496fb;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 a0f87b2..3aa604e 100644 --- a/src/main/java/net/pterodactylus/sone/data/Sone.java +++ b/src/main/java/net/pterodactylus/sone/data/Sone.java @@ -27,9 +27,12 @@ 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 net.pterodactylus.util.validation.Validation; import freenet.keys.FreenetURI; /** @@ -40,7 +43,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,6 +59,15 @@ 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); @@ -81,6 +93,9 @@ public class Sone { /** The profile of this Sone. */ 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()); @@ -96,6 +111,12 @@ public class Sone { /** The IDs of all liked replies. */ private final Set likedReplyIds = Collections.synchronizedSet(new HashSet()); + /** The albums of this Sone. */ + private final List albums = Collections.synchronizedList(new ArrayList()); + + /** Sone-specific options. */ + private final Options options = new Options(); + /** * Creates a new Sone. * @@ -173,7 +194,7 @@ public class Sone { */ public Sone setRequestUri(FreenetURI requestUri) { if (this.requestUri == null) { - this.requestUri = requestUri.setDocName("Sone").setMetaString(new String[0]); + this.requestUri = requestUri.setKeyType("USK").setDocName("Sone").setMetaString(new String[0]); return this; } if (!this.requestUri.equalsKeypair(requestUri)) { @@ -201,7 +222,7 @@ public class Sone { */ public Sone setInsertUri(FreenetURI insertUri) { if (this.insertUri == null) { - this.insertUri = insertUri.setDocName("Sone").setMetaString(new String[0]); + this.insertUri = insertUri.setKeyType("USK").setDocName("Sone").setMetaString(new String[0]); return this; } if (!this.insertUri.equalsKeypair(insertUri)) { @@ -230,7 +251,7 @@ public class Sone { */ 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; @@ -281,6 +302,27 @@ public class Sone { } /** + * 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; + } + + /** * Returns all friend Sones of this Sone. * * @return The friend Sones of this Sone @@ -363,8 +405,10 @@ public class Sone { * @return This Sone (for method chaining) */ public synchronized Sone setPosts(Collection posts) { - this.posts.clear(); - this.posts.addAll(posts); + synchronized (this) { + this.posts.clear(); + this.posts.addAll(posts); + } return this; } @@ -557,35 +601,70 @@ public class Sone { } /** - * Returns a fingerprint of this Sone. The fingerprint only depends on data - * that is actually stored when a Sone is inserted. The fingerprint can be - * used to detect changes in Sone data and can also be used to detect if - * previous changes are reverted. + * Returns the albums of this Sone. + * + * @return The albums of this Sone + */ + public List 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 albums) { + Validation.begin().isNotNull("Albums", albums).check(); + this.albums.clear(); + for (Album album : albums) { + addAlbum(album); + } + } + + /** + * Removes an album from this Sone. * - * @return The fingerprint of 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 + */ + public Options getOptions() { + return options; + } + + // + // FINGERPRINTABLE METHODS + // + + /** + * {@inheritDoc} + */ + @Override public synchronized String getFingerprint() { StringBuilder fingerprint = new StringBuilder(); - fingerprint.append("Profile("); - if (profile.getFirstName() != null) { - fingerprint.append("FirstName(").append(profile.getFirstName()).append(')'); - } - if (profile.getMiddleName() != null) { - fingerprint.append("MiddleName(").append(profile.getMiddleName()).append(')'); - } - if (profile.getLastName() != null) { - fingerprint.append("LastName(").append(profile.getLastName()).append(')'); - } - if (profile.getBirthDay() != null) { - fingerprint.append("BirthDay(").append(profile.getBirthDay()).append(')'); - } - if (profile.getBirthMonth() != null) { - fingerprint.append("BirthMonth(").append(profile.getBirthMonth()).append(')'); - } - if (profile.getBirthYear() != null) { - fingerprint.append("BirthYear(").append(profile.getBirthYear()).append(')'); - } - fingerprint.append(")"); + fingerprint.append(profile.getFingerprint()); fingerprint.append("Posts("); for (Post post : getPosts()) { @@ -617,10 +696,55 @@ public class 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 flattenAlbums(Collection albums) { + List flatAlbums = new ArrayList(); + flatAlbums.addAll(albums); + int lastAlbumIndex = 0; + while (lastAlbumIndex < flatAlbums.size()) { + int previousAlbumCount = flatAlbums.size(); + for (Album album : new ArrayList(flatAlbums.subList(lastAlbumIndex, flatAlbums.size()))) { + flatAlbums.addAll(album.getAlbums()); + } + lastAlbumIndex = previousAlbumCount; + } + return flatAlbums; + } + + // + // INTERFACE Comparable + // + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(Sone sone) { + return NICE_NAME_COMPARATOR.compare(this, sone); + } + + // // OBJECT METHODS //