Call other Core method instead of database directly.
[Sone.git] / src / main / java / net / pterodactylus / sone / core / Core.java
index 26d21ed..13dfead 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Core.java - Copyright © 2010 David Roden
+ * Sone - Core.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
@@ -19,6 +19,7 @@ package net.pterodactylus.sone.core;
 
 import java.net.MalformedURLException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -46,6 +47,7 @@ import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.data.Sone.ShowCustomAvatars;
 import net.pterodactylus.sone.data.Sone.SoneStatus;
 import net.pterodactylus.sone.data.TemporaryImage;
+import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.fcp.FcpInterface;
 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired;
 import net.pterodactylus.sone.freenet.wot.Identity;
@@ -93,6 +95,9 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
        /** Whether we’re currently saving the configuration. */
        private boolean storingConfiguration = false;
 
+       /** The database. */
+       private Database database;
+
        /** The identity manager. */
        private final IdentityManager identityManager;
 
@@ -129,47 +134,39 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
        /* synchronize access on this on localSones. */
        private final Map<Sone, SoneRescuer> soneRescuers = new HashMap<Sone, SoneRescuer>();
 
-       /** All local Sones. */
-       /* synchronize access on this on itself. */
-       private Map<String, Sone> localSones = new HashMap<String, Sone>();
-
-       /** All remote Sones. */
-       /* synchronize access on this on itself. */
-       private Map<String, Sone> remoteSones = new HashMap<String, Sone>();
-
        /** All known Sones. */
-       private Set<String> knownSones = new HashSet<String>();
+       private final Set<String> knownSones = new HashSet<String>();
 
        /** All posts. */
-       private Map<String, Post> posts = new HashMap<String, Post>();
+       private final Map<String, Post> posts = new HashMap<String, Post>();
 
        /** All known posts. */
-       private Set<String> knownPosts = new HashSet<String>();
+       private final Set<String> knownPosts = new HashSet<String>();
 
        /** All replies. */
-       private Map<String, PostReply> replies = new HashMap<String, PostReply>();
+       private final Map<String, PostReply> replies = new HashMap<String, PostReply>();
 
        /** All known replies. */
-       private Set<String> knownReplies = new HashSet<String>();
+       private final Set<String> knownReplies = new HashSet<String>();
 
        /** All bookmarked posts. */
        /* synchronize access on itself. */
-       private Set<String> bookmarkedPosts = new HashSet<String>();
+       private final Set<String> bookmarkedPosts = new HashSet<String>();
 
        /** Trusted identities, sorted by own identities. */
-       private Map<OwnIdentity, Set<Identity>> trustedIdentities = Collections.synchronizedMap(new HashMap<OwnIdentity, Set<Identity>>());
+       private final Map<OwnIdentity, Set<Identity>> trustedIdentities = Collections.synchronizedMap(new HashMap<OwnIdentity, Set<Identity>>());
 
        /** All known albums. */
-       private Map<String, Album> albums = new HashMap<String, Album>();
+       private final Map<String, Album> albums = new HashMap<String, Album>();
 
        /** All known images. */
-       private Map<String, Image> images = new HashMap<String, Image>();
+       private final Map<String, Image> images = new HashMap<String, Image>();
 
        /** All temporary images. */
-       private Map<String, TemporaryImage> temporaryImages = new HashMap<String, TemporaryImage>();
+       private final Map<String, TemporaryImage> temporaryImages = new HashMap<String, TemporaryImage>();
 
        /** Ticker for threads that mark own elements as known. */
-       private Ticker localElementTicker = new Ticker();
+       private final Ticker localElementTicker = new Ticker();
 
        /** The time the configuration was last touched. */
        private volatile long lastConfigurationUpdate;
@@ -179,14 +176,17 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *
         * @param configuration
         *            The configuration of the core
+        * @param database
+        *            The database to use
         * @param freenetInterface
         *            The freenet interface
         * @param identityManager
         *            The identity manager
         */
-       public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager) {
+       public Core(Configuration configuration, Database database, FreenetInterface freenetInterface, IdentityManager identityManager) {
                super("Sone Core");
                this.configuration = configuration;
+               this.database = database;
                this.freenetInterface = freenetInterface;
                this.identityManager = identityManager;
                this.soneDownloader = new SoneDownloader(this, freenetInterface);
@@ -280,7 +280,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         */
        public SoneRescuer getSoneRescuer(Sone sone) {
                Validation.begin().isNotNull("Sone", sone).check().is("Local Sone", isLocalSone(sone)).check();
-               synchronized (localSones) {
+               synchronized (soneRescuers) {
                        SoneRescuer soneRescuer = soneRescuers.get(sone);
                        if (soneRescuer == null) {
                                soneRescuer = new SoneRescuer(this, soneDownloader, sone);
@@ -309,11 +309,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *
         * @return All Sones
         */
-       public Set<Sone> getSones() {
-               Set<Sone> allSones = new HashSet<Sone>();
-               allSones.addAll(getLocalSones());
-               allSones.addAll(getRemoteSones());
-               return allSones;
+       public Collection<Sone> getSones() {
+               return database.getSones();
        }
 
        /**
@@ -344,10 +341,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         */
        @Override
        public Sone getSone(String id, boolean create) {
-               if (isLocalSone(id)) {
-                       return getLocalSone(id);
-               }
-               return getRemoteSone(id, create);
+               return database.getSone(id, create);
        }
 
        /**
@@ -359,7 +353,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *         otherwise
         */
        public boolean hasSone(String id) {
-               return isLocalSone(id) || isRemoteSone(id);
+               return database.isLocalSone(id) || database.isRemoteSone(id);
        }
 
        /**
@@ -370,9 +364,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         * @return {@code true} if the given Sone is local, {@code false} otherwise
         */
        public boolean isLocalSone(Sone sone) {
-               synchronized (localSones) {
-                       return localSones.containsKey(sone.getId());
-               }
+               return database.isLocalSone(sone);
        }
 
        /**
@@ -384,9 +376,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *         otherwise
         */
        public boolean isLocalSone(String id) {
-               synchronized (localSones) {
-                       return localSones.containsKey(id);
-               }
+               return database.isLocalSone(id);
        }
 
        /**
@@ -394,10 +384,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *
         * @return All local Sones
         */
-       public Set<Sone> getLocalSones() {
-               synchronized (localSones) {
-                       return new HashSet<Sone>(localSones.values());
-               }
+       public Collection<Sone> getLocalSones() {
+               return database.getLocalSones();
        }
 
        /**
@@ -422,14 +410,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         * @return The Sone with the given ID, or {@code null}
         */
        public Sone getLocalSone(String id, boolean create) {
-               synchronized (localSones) {
-                       Sone sone = localSones.get(id);
-                       if ((sone == null) && create) {
-                               sone = new Sone(id);
-                               localSones.put(id, sone);
-                       }
-                       return sone;
-               }
+               return database.getLocalSone(id, create);
        }
 
        /**
@@ -437,10 +418,8 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *
         * @return All remote Sones
         */
-       public Set<Sone> getRemoteSones() {
-               synchronized (remoteSones) {
-                       return new HashSet<Sone>(remoteSones.values());
-               }
+       public Collection<Sone> getRemoteSones() {
+               return database.getRemoteSones();
        }
 
        /**
@@ -454,14 +433,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         * @return The Sone with the given ID
         */
        public Sone getRemoteSone(String id, boolean create) {
-               synchronized (remoteSones) {
-                       Sone sone = remoteSones.get(id);
-                       if ((sone == null) && create && (id != null) && (id.length() == 43)) {
-                               sone = new Sone(id);
-                               remoteSones.put(id, sone);
-                       }
-                       return sone;
-               }
+               return database.getRemoteSone(id, create);
        }
 
        /**
@@ -473,9 +445,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *         otherwise
         */
        public boolean isRemoteSone(Sone sone) {
-               synchronized (remoteSones) {
-                       return remoteSones.containsKey(sone.getId());
-               }
+               return database.isRemoteSone(sone);
        }
 
        /**
@@ -487,9 +457,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *         {@code false} otherwise
         */
        public boolean isRemoteSone(String id) {
-               synchronized (remoteSones) {
-                       return remoteSones.containsKey(id);
-               }
+               return database.isRemoteSone(id);
        }
 
        /**
@@ -632,7 +600,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         * @return All replies for the given post
         */
        public List<PostReply> getReplies(Post post) {
-               Set<Sone> sones = getSones();
+               Collection<Sone> sones = getSones();
                List<PostReply> replies = new ArrayList<PostReply>();
                for (Sone sone : sones) {
                        for (PostReply reply : sone.getReplies()) {
@@ -853,27 +821,25 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                        logger.log(Level.WARNING, "Given OwnIdentity is null!");
                        return null;
                }
-               synchronized (localSones) {
-                       final Sone sone;
-                       try {
-                               sone = getLocalSone(ownIdentity.getId()).setIdentity(ownIdentity).setInsertUri(new FreenetURI(ownIdentity.getInsertUri())).setRequestUri(new FreenetURI(ownIdentity.getRequestUri()));
-                       } catch (MalformedURLException mue1) {
-                               logger.log(Level.SEVERE, String.format("Could not convert the Identity’s URIs to Freenet URIs: %s, %s", ownIdentity.getInsertUri(), ownIdentity.getRequestUri()), mue1);
-                               return null;
-                       }
-                       sone.setLatestEdition(Numbers.safeParseLong(ownIdentity.getProperty("Sone.LatestEdition"), (long) 0));
-                       sone.setClient(new Client("Sone", SonePlugin.VERSION.toString()));
-                       sone.setKnown(true);
-                       /* TODO - load posts ’n stuff */
-                       localSones.put(ownIdentity.getId(), sone);
-                       final SoneInserter soneInserter = new SoneInserter(this, freenetInterface, sone);
-                       soneInserter.addSoneInsertListener(this);
-                       soneInserters.put(sone, soneInserter);
-                       sone.setStatus(SoneStatus.idle);
-                       loadSone(sone);
-                       soneInserter.start();
-                       return sone;
+               Sone sone;
+               try {
+                       sone = getLocalSone(ownIdentity.getId()).setIdentity(ownIdentity).setInsertUri(new FreenetURI(ownIdentity.getInsertUri())).setRequestUri(new FreenetURI(ownIdentity.getRequestUri()));
+               } catch (MalformedURLException mue1) {
+                       logger.log(Level.SEVERE, String.format("Could not convert the Identity’s URIs to Freenet URIs: %s, %s", ownIdentity.getInsertUri(), ownIdentity.getRequestUri()), mue1);
+                       return null;
                }
+               sone.setLatestEdition(Numbers.safeParseLong(ownIdentity.getProperty("Sone.LatestEdition"), (long) 0));
+               sone.setClient(new Client("Sone", SonePlugin.VERSION.toString()));
+               sone.setKnown(true);
+               database.saveSone(sone);
+               /* TODO - load posts ’n stuff */
+               final SoneInserter soneInserter = new SoneInserter(this, freenetInterface, sone);
+               soneInserter.addSoneInsertListener(this);
+               soneInserters.put(sone, soneInserter);
+               sone.setStatus(SoneStatus.idle);
+               loadSone(sone);
+               soneInserter.start();
+               return sone;
        }
 
        /**
@@ -915,37 +881,36 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                        logger.log(Level.WARNING, "Given Identity is null!");
                        return null;
                }
-               synchronized (remoteSones) {
-                       final Sone sone = getRemoteSone(identity.getId(), true).setIdentity(identity);
-                       boolean newSone = sone.getRequestUri() == null;
-                       sone.setRequestUri(getSoneUri(identity.getRequestUri()));
-                       sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0));
+               final Sone sone = getRemoteSone(identity.getId(), true).setIdentity(identity);
+               boolean newSone = sone.getRequestUri() == null;
+               sone.setRequestUri(getSoneUri(identity.getRequestUri()));
+               sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0));
+               if (newSone) {
+                       synchronized (knownSones) {
+                               newSone = !knownSones.contains(sone.getId());
+                       }
+                       sone.setKnown(!newSone);
                        if (newSone) {
-                               synchronized (knownSones) {
-                                       newSone = !knownSones.contains(sone.getId());
-                               }
-                               sone.setKnown(!newSone);
-                               if (newSone) {
-                                       coreListenerManager.fireNewSoneFound(sone);
-                                       for (Sone localSone : getLocalSones()) {
-                                               if (localSone.getOptions().getBooleanOption("AutoFollow").get()) {
-                                                       followSone(localSone, sone);
-                                               }
+                               coreListenerManager.fireNewSoneFound(sone);
+                               for (Sone localSone : getLocalSones()) {
+                                       if (localSone.getOptions().getBooleanOption("AutoFollow").get()) {
+                                               followSone(localSone, sone);
                                        }
                                }
                        }
-                       soneDownloader.addSone(sone);
-                       soneDownloaders.execute(new Runnable() {
+               }
+               database.saveSone(sone);
+               soneDownloader.addSone(sone);
+               soneDownloaders.execute(new Runnable() {
 
-                               @Override
-                               @SuppressWarnings("synthetic-access")
-                               public void run() {
-                                       soneDownloader.fetchSone(sone, sone.getRequestUri());
-                               }
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void run() {
+                               soneDownloader.fetchSone(sone, sone.getRequestUri());
+                       }
 
-                       });
-                       return sone;
-               }
+               });
+               return sone;
        }
 
        /**
@@ -1269,16 +1234,14 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                        logger.log(Level.WARNING, String.format("Tried to delete Sone of non-own identity: %s", sone));
                        return;
                }
-               synchronized (localSones) {
-                       if (!localSones.containsKey(sone.getId())) {
-                               logger.log(Level.WARNING, String.format("Tried to delete non-local Sone: %s", sone));
-                               return;
-                       }
-                       localSones.remove(sone.getId());
-                       SoneInserter soneInserter = soneInserters.remove(sone);
-                       soneInserter.removeSoneInsertListener(this);
-                       soneInserter.stop();
+               if (!database.isLocalSone(sone)) {
+                       logger.log(Level.WARNING, String.format("Tried to delete non-local Sone: %s", sone));
+                       return;
                }
+               database.removeSone(sone.getId());
+               SoneInserter soneInserter = soneInserters.remove(sone);
+               soneInserter.removeSoneInsertListener(this);
+               soneInserter.stop();
                try {
                        ((OwnIdentity) sone.getIdentity()).removeContext("Sone");
                        ((OwnIdentity) sone.getIdentity()).removeProperty("Sone.LatestEdition");
@@ -1456,7 +1419,9 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                                }
                                parentAlbum.addAlbum(album);
                        } else {
-                               topLevelAlbums.add(album);
+                               if (!topLevelAlbums.contains(album)) {
+                                       topLevelAlbums.add(album);
+                               }
                        }
                }
 
@@ -1990,11 +1955,9 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         */
        @Override
        public void serviceStop() {
-               synchronized (localSones) {
-                       for (SoneInserter soneInserter : soneInserters.values()) {
-                               soneInserter.removeSoneInsertListener(this);
-                               soneInserter.stop();
-                       }
+               for (SoneInserter soneInserter : soneInserters.values()) {
+                       soneInserter.removeSoneInsertListener(this);
+                       soneInserter.stop();
                }
                updateChecker.stop();
                updateChecker.removeUpdateListener(this);
@@ -2493,9 +2456,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                                }
                        }
                }
-               synchronized (remoteSones) {
-                       remoteSones.remove(identity.getId());
-               }
+               database.removeSone(identity.getId());
                coreListenerManager.fireSoneRemoved(sone);
        }