Rename album name to album title.
[Sone.git] / src / main / java / net / pterodactylus / sone / core / Core.java
index 7dc398e..06a1467 100644 (file)
@@ -31,7 +31,9 @@ import java.util.logging.Logger;
 import net.pterodactylus.sone.core.Options.DefaultOption;
 import net.pterodactylus.sone.core.Options.Option;
 import net.pterodactylus.sone.core.Options.OptionWatcher;
+import net.pterodactylus.sone.data.Album;
 import net.pterodactylus.sone.data.Client;
+import net.pterodactylus.sone.data.Image;
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.Profile;
 import net.pterodactylus.sone.data.Profile.Field;
@@ -165,6 +167,12 @@ public class Core implements IdentityListener, UpdateListener {
        /** Trusted identities, sorted by own identities. */
        private Map<OwnIdentity, Set<Identity>> trustedIdentities = Collections.synchronizedMap(new HashMap<OwnIdentity, Set<Identity>>());
 
+       /** All known albums. */
+       private Map<String, Album> albums = new HashMap<String, Album>();
+
+       /** All known images. */
+       private Map<String, Image> images = new HashMap<String, Image>();
+
        /**
         * Creates a new core.
         *
@@ -722,6 +730,75 @@ public class Core implements IdentityListener, UpdateListener {
                return posts;
        }
 
+       /**
+        * Returns the album with the given ID, creating a new album if no album
+        * with the given ID can be found.
+        *
+        * @param albumId
+        *            The ID of the album
+        * @return The album with the given ID
+        */
+       public Album getAlbum(String albumId) {
+               return getAlbum(albumId, true);
+       }
+
+       /**
+        * Returns the album with the given ID, optionally creating a new album if
+        * an album with the given ID can not be found.
+        *
+        * @param albumId
+        *            The ID of the album
+        * @param create
+        *            {@code true} to create a new album if none exists for the
+        *            given ID
+        * @return The album with the given ID, or {@code null} if no album with the
+        *         given ID exists and {@code create} is {@code false}
+        */
+       public Album getAlbum(String albumId, boolean create) {
+               synchronized (albums) {
+                       Album album = albums.get(albumId);
+                       if (create && (album == null)) {
+                               album = new Album(albumId);
+                               albums.put(albumId, album);
+                       }
+                       return album;
+               }
+       }
+
+       /**
+        * Returns the image with the given ID, creating it if necessary.
+        *
+        * @param imageId
+        *            The ID of the image
+        * @return The image with the given ID
+        */
+       public Image getImage(String imageId) {
+               return getImage(imageId, true);
+       }
+
+       /**
+        * Returns the image with the given ID, optionally creating it if it does
+        * not exist.
+        *
+        * @param imageId
+        *            The ID of the image
+        * @param create
+        *            {@code true} to create an image if none exists with the given
+        *            ID
+        * @return The image with the given ID, or {@code null} if none exists and
+        *         none was created
+        */
+       public Image getImage(String imageId, boolean create) {
+               synchronized (images) {
+                       Image image = images.get(imageId);
+                       if (create && (image == null)) {
+                               image = new Image(imageId);
+                               images.put(imageId, image);
+                       }
+                       return image;
+               }
+       }
+
        //
        // ACTIONS
        //
@@ -1242,6 +1319,38 @@ public class Core implements IdentityListener, UpdateListener {
                        friends.add(friendId);
                }
 
+               /* load albums. */
+               List<Album> topLevelAlbums = new ArrayList<Album>();
+               while (true) {
+                       String albumPrefix = sonePrefix + "/Albums/" + albums.size();
+                       String albumId = configuration.getStringValue(albumPrefix + "/ID").getValue(null);
+                       if (albumId == null) {
+                               break;
+                       }
+                       String albumTitle = configuration.getStringValue(albumPrefix + "/Title").getValue(null);
+                       String albumDescription = configuration.getStringValue(albumPrefix + "/Description").getValue(null);
+                       String albumParentId = configuration.getStringValue(albumPrefix + "/Parent").getValue(null);
+                       if ((albumTitle == null) || (albumDescription == null)) {
+                               logger.log(Level.WARNING, "Invalid album found, aborting load!");
+                               return;
+                       }
+                       Album album = getAlbum(albumId).setSone(sone).setTitle(albumTitle).setDescription(albumDescription);
+                       if (albumParentId != null) {
+                               Album parentAlbum = getAlbum(albumParentId, false);
+                               if (parentAlbum == null) {
+                                       logger.log(Level.WARNING, "Invalid parent album ID: " + albumParentId);
+                                       return;
+                               }
+                               parentAlbum.addAlbum(album);
+                       } else {
+                               topLevelAlbums.add(album);
+                       }
+               }
+
+               /* load options. */
+               sone.getOptions().addBooleanOption("AutoFollow", new DefaultOption<Boolean>(false));
+               sone.getOptions().getBooleanOption("AutoFollow").set(configuration.getBooleanValue(sonePrefix + "/Options/AutoFollow").getValue(null));
+
                /* if we’re still here, Sone was loaded successfully. */
                synchronized (sone) {
                        sone.setTime(soneTime);
@@ -1251,6 +1360,7 @@ public class Core implements IdentityListener, UpdateListener {
                        sone.setLikePostIds(likedPostIds);
                        sone.setLikeReplyIds(likedReplyIds);
                        sone.setFriends(friends);
+                       sone.setAlbums(topLevelAlbums);
                        soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint);
                }
                synchronized (newSones) {
@@ -1357,6 +1467,31 @@ public class Core implements IdentityListener, UpdateListener {
                        }
                        configuration.getStringValue(sonePrefix + "/Friends/" + friendCounter + "/ID").setValue(null);
 
+                       /* save albums. first, collect in a flat structure, top-level first. */
+                       List<Album> albums = new ArrayList<Album>();
+                       albums.addAll(sone.getAlbums());
+                       int lastAlbumIndex = 0;
+                       while (lastAlbumIndex < albums.size()) {
+                               int previousAlbumCount = albums.size();
+                               for (Album album : new ArrayList<Album>(albums.subList(lastAlbumIndex, albums.size()))) {
+                                       albums.addAll(album.getAlbums());
+                               }
+                               lastAlbumIndex = previousAlbumCount;
+                       }
+
+                       int albumCounter = 0;
+                       for (Album album : albums) {
+                               String albumPrefix = sonePrefix + "/Albums/" + albumCounter++;
+                               configuration.getStringValue(albumPrefix + "/ID").setValue(album.getId());
+                               configuration.getStringValue(albumPrefix + "/Title").setValue(album.getTitle());
+                               configuration.getStringValue(albumPrefix + "/Description").setValue(album.getDescription());
+                               configuration.getStringValue(albumPrefix + "/Parent").setValue(album.getParent() == null ? null : album.getParent().getId());
+                       }
+                       configuration.getStringValue(sonePrefix + "/Albums/" + albumCounter + "/ID").setValue(null);
+
+                       /* save options. */
+                       configuration.getBooleanValue(sonePrefix + "/Options/AutoFollow").setValue(sone.getOptions().getBooleanOption("AutoFollow").getReal());
+
                        configuration.save();
                        logger.log(Level.INFO, "Sone %s saved.", sone);
                } catch (ConfigurationException ce1) {
@@ -1605,6 +1740,41 @@ public class Core implements IdentityListener, UpdateListener {
        }
 
        /**
+        * Creates a new top-level album for the given Sone.
+        *
+        * @param sone
+        *            The Sone to create the album for
+        * @return The new album
+        */
+       public Album createAlbum(Sone sone) {
+               return createAlbum(sone, null);
+       }
+
+       /**
+        * Creates a new album for the given Sone.
+        *
+        * @param sone
+        *            The Sone to create the album for
+        * @param parent
+        *            The parent of the album (may be {@code null} to create a
+        *            top-level album)
+        * @return The new album
+        */
+       public Album createAlbum(Sone sone, Album parent) {
+               Album album = new Album();
+               synchronized (albums) {
+                       albums.put(album.getId(), album);
+               }
+               album.setSone(sone);
+               if (parent != null) {
+                       parent.addAlbum(album);
+               } else {
+                       sone.addAlbum(album);
+               }
+               return album;
+       }
+
+       /**
         * Starts the core.
         */
        public void start() {