Move plugin connector and related classes to its own package.
[Sone.git] / src / main / java / net / pterodactylus / sone / freenet / wot / IdentityManager.java
index e416cd1..fc9d651 100644 (file)
@@ -25,8 +25,7 @@ import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import net.pterodactylus.util.filter.Filter;
-import net.pterodactylus.util.filter.Filters;
+import net.pterodactylus.sone.freenet.plugin.PluginException;
 import net.pterodactylus.util.logging.Logging;
 import net.pterodactylus.util.service.AbstractService;
 
@@ -43,6 +42,11 @@ import net.pterodactylus.util.service.AbstractService;
  */
 public class IdentityManager extends AbstractService {
 
+       /** Object used for synchronization. */
+       private final Object syncObject = new Object() {
+               /* inner class for better lock names. */
+       };
+
        /** The logger. */
        private static final Logger logger = Logging.getLogger(IdentityManager.class);
 
@@ -55,8 +59,9 @@ public class IdentityManager extends AbstractService {
        /** The context to filter for. */
        private volatile String context;
 
-       /** Whether the Web of Trust plugin is connected. */
-       private volatile boolean wotPluginConnected = false;
+       /** The currently known own identities. */
+       /* synchronize access on syncObject. */
+       private Map<String, OwnIdentity> currentOwnIdentities = new HashMap<String, OwnIdentity>();
 
        /**
         * Creates a new identity manager.
@@ -115,7 +120,13 @@ public class IdentityManager extends AbstractService {
         *         {@code false} otherwise
         */
        public boolean isConnected() {
-               return wotPluginConnected;
+               try {
+                       webOfTrustConnector.ping();
+                       return true;
+               } catch (PluginException pe1) {
+                       /* not connected, ignore. */
+                       return false;
+               }
        }
 
        /**
@@ -142,12 +153,15 @@ public class IdentityManager extends AbstractService {
         */
        public Set<OwnIdentity> getAllOwnIdentities() {
                try {
-                       Set<OwnIdentity> allOwnIdentities = webOfTrustConnector.loadAllOwnIdentities();
-                       wotPluginConnected = true;
-                       return allOwnIdentities;
+                       Set<OwnIdentity> ownIdentities = webOfTrustConnector.loadAllOwnIdentities();
+                       Map<String, OwnIdentity> newOwnIdentities = new HashMap<String, OwnIdentity>();
+                       for (OwnIdentity ownIdentity : ownIdentities) {
+                               newOwnIdentities.put(ownIdentity.getId(), ownIdentity);
+                       }
+                       checkOwnIdentities(newOwnIdentities);
+                       return ownIdentities;
                } catch (PluginException pe1) {
                        logger.log(Level.WARNING, "Could not load all own identities!", pe1);
-                       wotPluginConnected = false;
                        return Collections.emptySet();
                }
        }
@@ -170,11 +184,9 @@ public class IdentityManager extends AbstractService {
                }
                try {
                        webOfTrustConnector.addContext(ownIdentity, context);
-                       wotPluginConnected = true;
                        ownIdentity.addContext(context);
                } catch (PluginException pe1) {
                        logger.log(Level.WARNING, "Could not add context " + context + " to OwnIdentity " + ownIdentity + ".", pe1);
-                       wotPluginConnected = false;
                }
        }
 
@@ -192,11 +204,9 @@ public class IdentityManager extends AbstractService {
                }
                try {
                        webOfTrustConnector.removeContext(ownIdentity, context);
-                       wotPluginConnected = true;
                        ownIdentity.removeContext(context);
                } catch (PluginException pe1) {
                        logger.log(Level.WARNING, "Could not remove context " + context + " from OwnIdentity " + ownIdentity + ".", pe1);
-                       wotPluginConnected = false;
                }
        }
 
@@ -213,11 +223,9 @@ public class IdentityManager extends AbstractService {
        public void setProperty(OwnIdentity ownIdentity, String name, String value) {
                try {
                        webOfTrustConnector.setProperty(ownIdentity, name, value);
-                       wotPluginConnected = true;
                        ownIdentity.setProperty(name, value);
                } catch (PluginException pe1) {
                        logger.log(Level.WARNING, "Could not set property “" + name + "” to “" + value + "” for OwnIdentity: " + ownIdentity, pe1);
-                       wotPluginConnected = false;
                }
        }
 
@@ -232,11 +240,9 @@ public class IdentityManager extends AbstractService {
        public void removeProperty(OwnIdentity ownIdentity, String name) {
                try {
                        webOfTrustConnector.removeProperty(ownIdentity, name);
-                       wotPluginConnected = true;
                        ownIdentity.removeProperty(name);
                } catch (PluginException pe1) {
                        logger.log(Level.WARNING, "Could not remove property “" + name + "” from OwnIdentity: " + ownIdentity, pe1);
-                       wotPluginConnected = false;
                }
        }
 
@@ -250,7 +256,6 @@ public class IdentityManager extends AbstractService {
        @Override
        protected void serviceRun() {
                Map<String, Identity> oldIdentities = Collections.emptyMap();
-               Map<String, OwnIdentity> oldOwnIdentities = Collections.emptyMap();
                while (!shouldStop()) {
                        Map<String, Identity> currentIdentities = new HashMap<String, Identity>();
                        Map<String, OwnIdentity> currentOwnIdentities = new HashMap<String, OwnIdentity>();
@@ -258,33 +263,23 @@ public class IdentityManager extends AbstractService {
                        /* get all identities with the wanted context from WoT. */
                        Set<OwnIdentity> ownIdentities;
                        try {
-                               ownIdentities = Filters.filteredSet(webOfTrustConnector.loadAllOwnIdentities(), new Filter<OwnIdentity>() {
-
-                                       @Override
-                                       @SuppressWarnings("synthetic-access")
-                                       public boolean filterObject(OwnIdentity ownIdentity) {
-                                               return (context == null) || ownIdentity.hasContext(context);
-                                       }
+                               ownIdentities = webOfTrustConnector.loadAllOwnIdentities();
 
-                               });
+                               /* check for changes. */
                                for (OwnIdentity ownIdentity : ownIdentities) {
                                        currentOwnIdentities.put(ownIdentity.getId(), ownIdentity);
-                                       for (Identity identity : webOfTrustConnector.loadTrustedIdentities(ownIdentity, context)) {
-                                               currentIdentities.put(identity.getId(), identity);
-                                       }
                                }
+                               checkOwnIdentities(currentOwnIdentities);
 
-                               /* find removed own identities: */
-                               for (OwnIdentity oldOwnIdentity : oldOwnIdentities.values()) {
-                                       if (!currentOwnIdentities.containsKey(oldOwnIdentity.getId())) {
-                                               identityListenerManager.fireOwnIdentityRemoved(oldOwnIdentity);
+                               /* now filter for context and get all identities. */
+                               currentOwnIdentities.clear();
+                               for (OwnIdentity ownIdentity : ownIdentities) {
+                                       if ((context != null) && !ownIdentity.hasContext(context)) {
+                                               continue;
                                        }
-                               }
-
-                               /* find added own identities. */
-                               for (OwnIdentity currentOwnIdentity : currentOwnIdentities.values()) {
-                                       if (!oldOwnIdentities.containsKey(currentOwnIdentity.getId())) {
-                                               identityListenerManager.fireOwnIdentityAdded(currentOwnIdentity);
+                                       currentOwnIdentities.put(ownIdentity.getId(), ownIdentity);
+                                       for (Identity identity : webOfTrustConnector.loadTrustedIdentities(ownIdentity, context)) {
+                                               currentIdentities.put(identity.getId(), identity);
                                        }
                                }
 
@@ -302,6 +297,26 @@ public class IdentityManager extends AbstractService {
                                        }
                                }
 
+                               /* check for changes in the contexts. */
+                               for (Identity oldIdentity : oldIdentities.values()) {
+                                       if (!currentIdentities.containsKey(oldIdentity.getId())) {
+                                               continue;
+                                       }
+                                       Identity newIdentity = currentIdentities.get(oldIdentity.getId());
+                                       Set<String> oldContexts = oldIdentity.getContexts();
+                                       Set<String> newContexts = newIdentity.getContexts();
+                                       if (oldContexts.size() != newContexts.size()) {
+                                               identityListenerManager.fireIdentityUpdated(newIdentity);
+                                               continue;
+                                       }
+                                       for (String oldContext : oldContexts) {
+                                               if (!newContexts.contains(oldContext)) {
+                                                       identityListenerManager.fireIdentityUpdated(newIdentity);
+                                                       break;
+                                               }
+                                       }
+                               }
+
                                /* check for changes in the properties. */
                                for (Identity oldIdentity : oldIdentities.values()) {
                                        if (!currentIdentities.containsKey(oldIdentity.getId())) {
@@ -324,7 +339,6 @@ public class IdentityManager extends AbstractService {
 
                                /* remember the current set of identities. */
                                oldIdentities = currentIdentities;
-                               oldOwnIdentities = currentOwnIdentities;
 
                        } catch (PluginException pe1) {
                                logger.log(Level.WARNING, "WoT has disappeared!", pe1);
@@ -335,4 +349,37 @@ public class IdentityManager extends AbstractService {
                }
        }
 
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Checks the given new list of own identities for added or removed own
+        * identities, as compared to {@link #currentOwnIdentities}.
+        *
+        * @param newOwnIdentities
+        *            The new own identities
+        */
+       private void checkOwnIdentities(Map<String, OwnIdentity> newOwnIdentities) {
+               synchronized (syncObject) {
+
+                       /* find removed own identities: */
+                       for (OwnIdentity oldOwnIdentity : currentOwnIdentities.values()) {
+                               if (!newOwnIdentities.containsKey(oldOwnIdentity.getId())) {
+                                       identityListenerManager.fireOwnIdentityRemoved(oldOwnIdentity);
+                               }
+                       }
+
+                       /* find added own identities. */
+                       for (OwnIdentity currentOwnIdentity : newOwnIdentities.values()) {
+                               if (!currentOwnIdentities.containsKey(currentOwnIdentity.getId())) {
+                                       identityListenerManager.fireOwnIdentityAdded(currentOwnIdentity);
+                               }
+                       }
+
+                       currentOwnIdentities.clear();
+                       currentOwnIdentities.putAll(newOwnIdentities);
+               }
+       }
+
 }