Use static import for String.format.
[Sone.git] / src / main / java / net / pterodactylus / sone / core / Core.java
index 6d67c25..491e76f 100644 (file)
@@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Predicates.not;
 import static com.google.common.collect.FluentIterable.from;
+import static java.lang.String.format;
 import static net.pterodactylus.sone.data.Identified.GET_ID;
 import static net.pterodactylus.sone.data.Sone.LOCAL_SONE_FILTER;
 import static net.pterodactylus.sone.data.Sone.TO_FREENET_URI;
@@ -172,10 +173,6 @@ public class Core extends AbstractService implements SoneProvider {
        /* synchronize access on this on sones. */
        private final Map<Sone, SoneRescuer> soneRescuers = new HashMap<Sone, SoneRescuer>();
 
-       /** All Sones. */
-       /* synchronize access on this on itself. */
-       private final Map<String, Sone> sones = new HashMap<String, Sone>();
-
        /** All known Sones. */
        private final Set<String> knownSones = new HashSet<String>();
 
@@ -295,7 +292,7 @@ public class Core extends AbstractService implements SoneProvider {
        public SoneRescuer getSoneRescuer(Sone sone) {
                checkNotNull(sone, "sone must not be null");
                checkArgument(sone.isLocal(), "sone must be local");
-               synchronized (sones) {
+               synchronized (soneRescuers) {
                        SoneRescuer soneRescuer = soneRescuers.get(sone);
                        if (soneRescuer == null) {
                                soneRescuer = new SoneRescuer(this, soneDownloader, sone);
@@ -321,9 +318,7 @@ public class Core extends AbstractService implements SoneProvider {
 
        @Override
        public Collection<Sone> getSones() {
-               synchronized (sones) {
-                       return ImmutableSet.copyOf(sones.values());
-               }
+               return database.getSones();
        }
 
        @Override
@@ -333,22 +328,12 @@ public class Core extends AbstractService implements SoneProvider {
 
        @Override
        public Optional<Sone> getSone(String id) {
-               synchronized (sones) {
-                       return Optional.fromNullable(sones.get(id));
-               }
+               return database.getSone(id);
        }
 
        @Override
        public Collection<Sone> getLocalSones() {
-               synchronized (sones) {
-                       return from(sones.values()).filter(new Predicate<Sone>() {
-
-                               @Override
-                               public boolean apply(Sone sone) {
-                                       return sone.isLocal();
-                               }
-                       }).toSet();
-               }
+               return database.getLocalSones();
        }
 
        /**
@@ -364,15 +349,7 @@ public class Core extends AbstractService implements SoneProvider {
 
        @Override
        public Collection<Sone> getRemoteSones() {
-               synchronized (sones) {
-                       return from(sones.values()).filter(new Predicate<Sone>() {
-
-                               @Override
-                               public boolean apply(Sone sone) {
-                                       return !sone.isLocal();
-                               }
-                       }).toSet();
-               }
+               return database.getRemoteSones();
        }
 
        /**
@@ -524,14 +501,14 @@ public class Core extends AbstractService implements SoneProvider {
                        logger.log(Level.WARNING, "Given OwnIdentity is null!");
                        return null;
                }
-               logger.info(String.format("Adding Sone from OwnIdentity: %s", ownIdentity));
-               synchronized (sones) {
+               logger.info(format("Adding Sone from OwnIdentity: %s", ownIdentity));
+               synchronized (soneRescuers) {
                        final Sone sone;
                        sone = database.newSoneBuilder().by(ownIdentity.getId()).local().using(new Client("Sone", SonePlugin.VERSION.toString())).build(Optional.<SoneCreated>absent());
                        sone.modify().setLatestEdition(Numbers.safeParseLong(ownIdentity.getProperty("Sone.LatestEdition"), (long) 0)).update();
                        sone.setKnown(true);
                        /* TODO - load posts ’n stuff */
-                       sones.put(ownIdentity.getId(), sone);
+                       database.storeSone(sone);
                        final SoneInserter soneInserter = new SoneInserter(this, eventBus, freenetInterface, sone);
                        soneInserters.put(sone, soneInserter);
                        sone.setStatus(SoneStatus.idle);
@@ -550,7 +527,7 @@ public class Core extends AbstractService implements SoneProvider {
         */
        public Sone createSone(OwnIdentity ownIdentity) {
                if (!webOfTrustUpdater.addContextWait(ownIdentity, "Sone")) {
-                       logger.log(Level.SEVERE, String.format("Could not add “Sone” context to own identity: %s", ownIdentity));
+                       logger.log(Level.SEVERE, format("Could not add “Sone” context to own identity: %s", ownIdentity));
                        return null;
                }
                Sone sone = addLocalSone(ownIdentity);
@@ -578,13 +555,13 @@ public class Core extends AbstractService implements SoneProvider {
                        logger.log(Level.WARNING, "Given Identity is null!");
                        return null;
                }
-               synchronized (sones) {
+               synchronized (soneRescuers) {
                        Optional<Sone> existingSone = database.getSone(identity.getId());
                        if (existingSone.isPresent() && existingSone.get().isLocal()) {
                                return existingSone.get();
                        }
                        boolean newSone = !existingSone.isPresent();
-                       final Sone sone = newSone ? database.newSoneBuilder().by(identity.getId()).build(Optional.<SoneCreated>absent()) : existingSone.get();
+                       final Sone sone = newSone ? database.newSoneBuilder().by(identity.getId()).using(new Client("Sone", SonePlugin.VERSION.toString())).build(Optional.<SoneCreated>absent()) : existingSone.get();
                        sone.modify().setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0)).update();
                        if (newSone) {
                                synchronized (knownSones) {
@@ -767,7 +744,7 @@ public class Core extends AbstractService implements SoneProvider {
                Optional<Sone> storedSone = getSone(sone.getId());
                if (storedSone.isPresent()) {
                        if (!soneRescueMode && !(sone.getTime() > storedSone.get().getTime())) {
-                               logger.log(Level.FINE, String.format("Downloaded Sone %s is not newer than stored Sone %s.", sone, storedSone));
+                               logger.log(Level.FINE, format("Downloaded Sone %s is not newer than stored Sone %s.", sone, storedSone));
                                return;
                        }
                        /* find removed posts. */
@@ -783,7 +760,7 @@ public class Core extends AbstractService implements SoneProvider {
                                        continue;
                                }
                                if (newPost.getTime() < getSoneFollowingTime(sone)) {
-                                       newPost.setKnown(true);
+                                       newPost.setKnown();
                                } else if (!newPost.isKnown()) {
                                        eventBus.post(new NewPostFoundEvent(newPost));
                                }
@@ -821,7 +798,7 @@ public class Core extends AbstractService implements SoneProvider {
                                        database.storeImage(image);
                                }
                        }
-                       synchronized (sones) {
+                       synchronized (soneRescuers) {
                                sone.setOptions(storedSone.get().getOptions());
                                sone.setKnown(storedSone.get().isKnown());
                                sone.setStatus((sone.getTime() == 0) ? SoneStatus.unknown : SoneStatus.idle);
@@ -829,7 +806,7 @@ public class Core extends AbstractService implements SoneProvider {
                                        soneInserters.get(storedSone.get()).setSone(sone);
                                        touchConfiguration();
                                }
-                               sones.put(sone.getId(), sone);
+                               database.storeSone(sone);
                        }
                }
        }
@@ -844,15 +821,14 @@ public class Core extends AbstractService implements SoneProvider {
         */
        public void deleteSone(Sone sone) {
                if (!(sone.getIdentity() instanceof OwnIdentity)) {
-                       logger.log(Level.WARNING, String.format("Tried to delete Sone of non-own identity: %s", sone));
+                       logger.log(Level.WARNING, format("Tried to delete Sone of non-own identity: %s", sone));
                        return;
                }
-               synchronized (sones) {
+               synchronized (soneRescuers) {
                        if (!getLocalSones().contains(sone)) {
-                               logger.log(Level.WARNING, String.format("Tried to delete non-local Sone: %s", sone));
+                               logger.log(Level.WARNING, format("Tried to delete non-local Sone: %s", sone));
                                return;
                        }
-                       sones.remove(sone.getId());
                        SoneInserter soneInserter = soneInserters.remove(sone);
                        soneInserter.stop();
                }
@@ -892,10 +868,10 @@ public class Core extends AbstractService implements SoneProvider {
         */
        public void loadSone(Sone sone) {
                if (!sone.isLocal()) {
-                       logger.log(Level.FINE, String.format("Tried to load non-local Sone: %s", sone));
+                       logger.log(Level.FINE, format("Tried to load non-local Sone: %s", sone));
                        return;
                }
-               logger.info(String.format("Loading local Sone: %s", sone));
+               logger.info(format("Loading local Sone: %s", sone));
 
                /* initialize options. */
                sone.getOptions().addBooleanOption("AutoFollow", new DefaultOption<Boolean>(false));
@@ -1096,14 +1072,14 @@ public class Core extends AbstractService implements SoneProvider {
                }
                database.storePosts(sone, posts);
                for (Post post : posts) {
-                       post.setKnown(true);
+                       post.setKnown();
                }
                database.storePostReplies(sone, replies);
                for (PostReply reply : replies) {
                        reply.modify().setKnown().update(Optional.<ReplyUpdated<PostReply>>absent());
                }
 
-               logger.info(String.format("Sone loaded successfully: %s", sone));
+               logger.info(format("Sone loaded successfully: %s", sone));
        }
 
        /**
@@ -1114,7 +1090,7 @@ public class Core extends AbstractService implements SoneProvider {
         */
        public void deletePost(Post post) {
                if (!post.getSone().isLocal()) {
-                       logger.log(Level.WARNING, String.format("Tried to delete post of non-local Sone: %s", post.getSone()));
+                       logger.log(Level.WARNING, format("Tried to delete post of non-local Sone: %s", post.getSone()));
                        return;
                }
                database.removePost(post);
@@ -1131,7 +1107,7 @@ public class Core extends AbstractService implements SoneProvider {
         *              The post to mark as known
         */
        public void markPostKnown(Post post) {
-               post.setKnown(true);
+               post.setKnown();
                eventBus.post(new MarkPostKnownEvent(post));
                touchConfiguration();
                for (PostReply reply : post.getReplies()) {
@@ -1182,7 +1158,7 @@ public class Core extends AbstractService implements SoneProvider {
        public void deleteReply(PostReply reply) {
                Sone sone = reply.getSone();
                if (!sone.isLocal()) {
-                       logger.log(Level.FINE, String.format("Tried to delete non-local reply: %s", reply));
+                       logger.log(Level.FINE, format("Tried to delete non-local reply: %s", reply));
                        return;
                }
                postReplyUpdated().get().replyUpdated(reply);
@@ -1303,7 +1279,7 @@ public class Core extends AbstractService implements SoneProvider {
        @Override
        public void serviceStop() {
                localElementTicker.shutdownNow();
-               synchronized (sones) {
+               synchronized (soneRescuers) {
                        for (Entry<Sone, SoneInserter> soneInserter : soneInserters.entrySet()) {
                                soneInserter.getValue().stop();
                                saveSone(soneInserter.getKey());
@@ -1314,8 +1290,8 @@ public class Core extends AbstractService implements SoneProvider {
                webOfTrustUpdater.stop();
                updateChecker.stop();
                soneDownloader.stop();
-               soneDownloaders.shutdown();
                identityManager.stop();
+               soneDownloaders.shutdownNow();
        }
 
        //
@@ -1331,15 +1307,15 @@ public class Core extends AbstractService implements SoneProvider {
         */
        private synchronized void saveSone(Sone sone) {
                if (!sone.isLocal()) {
-                       logger.log(Level.FINE, String.format("Tried to save non-local Sone: %s", sone));
+                       logger.log(Level.FINE, format("Tried to save non-local Sone: %s", sone));
                        return;
                }
                if (!(sone.getIdentity() instanceof OwnIdentity)) {
-                       logger.log(Level.WARNING, String.format("Local Sone without OwnIdentity found, refusing to save: %s", sone));
+                       logger.log(Level.WARNING, format("Local Sone without OwnIdentity found, refusing to save: %s", sone));
                        return;
                }
 
-               logger.log(Level.INFO, String.format("Saving Sone: %s", sone));
+               logger.log(Level.INFO, format("Saving Sone: %s", sone));
                try {
                        /* save Sone into configuration. */
                        String sonePrefix = "Sone/" + sone.getId();
@@ -1454,9 +1430,9 @@ public class Core extends AbstractService implements SoneProvider {
 
                        webOfTrustUpdater.setProperty((OwnIdentity) sone.getIdentity(), "Sone.LatestEdition", String.valueOf(sone.getLatestEdition()));
 
-                       logger.log(Level.INFO, String.format("Sone %s saved.", sone));
+                       logger.log(Level.INFO, format("Sone %s saved.", sone));
                } catch (ConfigurationException ce1) {
-                       logger.log(Level.WARNING, String.format("Could not save Sone: %s", sone), ce1);
+                       logger.log(Level.WARNING, format("Could not save Sone: %s", sone), ce1);
                }
        }
 
@@ -1505,9 +1481,6 @@ public class Core extends AbstractService implements SoneProvider {
                                configuration.getStringValue("SoneFollowingTimes/" + soneCounter + "/Sone").setValue(null);
                        }
 
-                       /* save known posts. */
-                       database.save();
-
                        /* save bookmarked posts. */
                        int bookmarkedPostCounter = 0;
                        synchronized (bookmarkedPosts) {
@@ -1522,8 +1495,6 @@ public class Core extends AbstractService implements SoneProvider {
 
                } catch (ConfigurationException ce1) {
                        logger.log(Level.SEVERE, "Could not store configuration!", ce1);
-               } catch (DatabaseException de1) {
-                       logger.log(Level.SEVERE, "Could not save database!", de1);
                } finally {
                        synchronized (configuration) {
                                storingConfiguration = false;
@@ -1631,7 +1602,7 @@ public class Core extends AbstractService implements SoneProvider {
                try {
                        options.getIntegerOption(optionName).set(configuration.getIntValue("Option/" + optionName).getValue(null));
                } catch (IllegalArgumentException iae1) {
-                       logger.log(Level.WARNING, String.format("Invalid value for %s in configuration, using default.", optionName));
+                       logger.log(Level.WARNING, format("Invalid value for %s in configuration, using default.", optionName));
                }
        }
 
@@ -1644,8 +1615,9 @@ public class Core extends AbstractService implements SoneProvider {
        @Subscribe
        public void ownIdentityAdded(OwnIdentityAddedEvent ownIdentityAddedEvent) {
                OwnIdentity ownIdentity = ownIdentityAddedEvent.ownIdentity();
-               logger.log(Level.FINEST, String.format("Adding OwnIdentity: %s", ownIdentity));
+               logger.log(Level.FINEST, format("Adding OwnIdentity: %s", ownIdentity));
                if (ownIdentity.hasContext("Sone")) {
+                       database.storeIdentity(ownIdentity);
                        addLocalSone(ownIdentity);
                }
        }
@@ -1659,7 +1631,7 @@ public class Core extends AbstractService implements SoneProvider {
        @Subscribe
        public void ownIdentityRemoved(OwnIdentityRemovedEvent ownIdentityRemovedEvent) {
                OwnIdentity ownIdentity = ownIdentityRemovedEvent.ownIdentity();
-               logger.log(Level.FINEST, String.format("Removing OwnIdentity: %s", ownIdentity));
+               logger.log(Level.FINEST, format("Removing OwnIdentity: %s", ownIdentity));
                trustedIdentities.removeAll(ownIdentity);
        }
 
@@ -1672,8 +1644,9 @@ public class Core extends AbstractService implements SoneProvider {
        @Subscribe
        public void identityAdded(IdentityAddedEvent identityAddedEvent) {
                Identity identity = identityAddedEvent.identity();
-               logger.log(Level.FINEST, String.format("Adding Identity: %s", identity));
+               logger.log(Level.FINEST, format("Adding Identity: %s", identity));
                trustedIdentities.put(identityAddedEvent.ownIdentity(), identity);
+               database.storeIdentity(identity);
                addRemoteSone(identity);
        }
 
@@ -1686,6 +1659,7 @@ public class Core extends AbstractService implements SoneProvider {
        @Subscribe
        public void identityUpdated(IdentityUpdatedEvent identityUpdatedEvent) {
                final Identity identity = identityUpdatedEvent.identity();
+               database.storeIdentity(identity);
                soneDownloaders.execute(new Runnable() {
 
                        @Override
@@ -1736,9 +1710,6 @@ public class Core extends AbstractService implements SoneProvider {
                for (PostReply reply : sone.get().getReplies()) {
                        eventBus.post(new PostReplyRemovedEvent(reply));
                }
-               synchronized (sones) {
-                       sones.remove(identity.getId());
-               }
                eventBus.post(new SoneRemovedEvent(sone.get()));
        }
 
@@ -1750,7 +1721,7 @@ public class Core extends AbstractService implements SoneProvider {
         */
        @Subscribe
        public void imageInsertFinished(ImageInsertFinishedEvent imageInsertFinishedEvent) {
-               logger.log(Level.WARNING, String.format("Image insert finished for %s: %s", imageInsertFinishedEvent.image(), imageInsertFinishedEvent.resultingUri()));
+               logger.log(Level.WARNING, format("Image insert finished for %s: %s", imageInsertFinishedEvent.image(), imageInsertFinishedEvent.resultingUri()));
                imageInsertFinishedEvent.image().modify().setKey(imageInsertFinishedEvent.resultingUri().toString()).update();
                deleteTemporaryImage(imageInsertFinishedEvent.image().getId());
                touchConfiguration();