X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Ffreenet%2Fwot%2FIdentityChangeDetector.java;fp=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Ffreenet%2Fwot%2FIdentityChangeDetector.java;h=0000000000000000000000000000000000000000;hp=8b2801193306567aa5c41abef80e5fb366109342;hb=d50730f6a330439e0e7ef97ca9329dffe72d5640;hpb=97fe04482ebb8a08e43294acde041c2975cbd8ee diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/IdentityChangeDetector.java b/src/main/java/net/pterodactylus/sone/freenet/wot/IdentityChangeDetector.java deleted file mode 100644 index 8b28011..0000000 --- a/src/main/java/net/pterodactylus/sone/freenet/wot/IdentityChangeDetector.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Sone - IdentityChangeDetector.java - Copyright © 2013–2019 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.pterodactylus.sone.freenet.wot; - -import static com.google.common.base.Optional.absent; -import static com.google.common.base.Optional.fromNullable; -import static com.google.common.base.Predicates.not; -import static com.google.common.collect.FluentIterable.from; -import static net.pterodactylus.sone.freenet.wot.Identity.TO_CONTEXTS; -import static net.pterodactylus.sone.freenet.wot.Identity.TO_PROPERTIES; - -import java.util.Collection; -import java.util.Map; -import java.util.Map.Entry; - -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableMap; - -/** - * Detects changes between two lists of {@link Identity}s. The detector can find - * added and removed identities, and for identities that exist in both list - * their contexts and properties are checked for added, removed, or (in case of - * properties) changed values. - */ -public class IdentityChangeDetector { - - private final Map oldIdentities; - private Optional onNewIdentity = absent(); - private Optional onRemovedIdentity = absent(); - private Optional onChangedIdentity = absent(); - private Optional onUnchangedIdentity = absent(); - - public IdentityChangeDetector(Collection oldIdentities) { - this.oldIdentities = convertToMap(oldIdentities); - } - - public void onNewIdentity(IdentityProcessor onNewIdentity) { - this.onNewIdentity = fromNullable(onNewIdentity); - } - - public void onRemovedIdentity(IdentityProcessor onRemovedIdentity) { - this.onRemovedIdentity = fromNullable(onRemovedIdentity); - } - - public void onChangedIdentity(IdentityProcessor onChangedIdentity) { - this.onChangedIdentity = fromNullable(onChangedIdentity); - } - - public void onUnchangedIdentity(IdentityProcessor onUnchangedIdentity) { - this.onUnchangedIdentity = fromNullable(onUnchangedIdentity); - } - - public void detectChanges(final Collection newIdentities) { - notifyForRemovedIdentities(from(oldIdentities.values()).filter(notContainedIn(newIdentities))); - notifyForNewIdentities(from(newIdentities).filter(notContainedIn(oldIdentities.values()))); - notifyForChangedIdentities(from(newIdentities).filter(containedIn(oldIdentities)).filter(hasChanged(oldIdentities))); - notifyForUnchangedIdentities(from(newIdentities).filter(containedIn(oldIdentities)).filter(not(hasChanged(oldIdentities)))); - } - - private void notifyForRemovedIdentities(Iterable identities) { - notify(onRemovedIdentity, identities); - } - - private void notifyForNewIdentities(FluentIterable newIdentities) { - notify(onNewIdentity, newIdentities); - } - - private void notifyForChangedIdentities(FluentIterable identities) { - notify(onChangedIdentity, identities); - } - - private void notifyForUnchangedIdentities(FluentIterable identities) { - notify(onUnchangedIdentity, identities); - } - - private void notify(Optional identityProcessor, Iterable identities) { - if (!identityProcessor.isPresent()) { - return; - } - for (Identity identity : identities) { - identityProcessor.get().processIdentity(identity); - } - } - - private static Predicate hasChanged(final Map oldIdentities) { - return new Predicate() { - @Override - public boolean apply(Identity identity) { - return (identity != null) && identityHasChanged(oldIdentities.get(identity.getId()), identity); - } - }; - } - - private static boolean identityHasChanged(Identity oldIdentity, Identity newIdentity) { - return identityHasNewContexts(oldIdentity, newIdentity) - || identityHasRemovedContexts(oldIdentity, newIdentity) - || identityHasNewProperties(oldIdentity, newIdentity) - || identityHasRemovedProperties(oldIdentity, newIdentity) - || identityHasChangedProperties(oldIdentity, newIdentity); - } - - private static boolean identityHasNewContexts(Identity oldIdentity, Identity newIdentity) { - return from(TO_CONTEXTS.apply(newIdentity)).anyMatch(notAContextOf(oldIdentity)); - } - - private static boolean identityHasRemovedContexts(Identity oldIdentity, Identity newIdentity) { - return from(TO_CONTEXTS.apply(oldIdentity)).anyMatch(notAContextOf(newIdentity)); - } - - private static boolean identityHasNewProperties(Identity oldIdentity, Identity newIdentity) { - return from(TO_PROPERTIES.apply(newIdentity).entrySet()).anyMatch(notAPropertyOf(oldIdentity)); - } - - private static boolean identityHasRemovedProperties(Identity oldIdentity, Identity newIdentity) { - return from(TO_PROPERTIES.apply(oldIdentity).entrySet()).anyMatch(notAPropertyOf(newIdentity)); - } - - private static boolean identityHasChangedProperties(Identity oldIdentity, Identity newIdentity) { - return from(TO_PROPERTIES.apply(oldIdentity).entrySet()).anyMatch(hasADifferentValueThanIn(newIdentity)); - } - - private static Predicate containedIn(final Map identities) { - return new Predicate() { - @Override - public boolean apply(Identity identity) { - return (identity != null) && identities.containsKey(identity.getId()); - } - }; - } - - private static Predicate notAContextOf(final Identity identity) { - return new Predicate() { - @Override - public boolean apply(String context) { - return (identity != null) && !identity.getContexts().contains(context); - } - }; - } - - private static Predicate notContainedIn(final Collection newIdentities) { - return new Predicate() { - @Override - public boolean apply(Identity identity) { - return (identity != null) && !newIdentities.contains(identity); - } - }; - } - - private static Predicate> notAPropertyOf(final Identity identity) { - return new Predicate>() { - @Override - public boolean apply(Entry property) { - return (property != null) && !identity.getProperties().containsKey(property.getKey()); - } - }; - } - - private static Predicate> hasADifferentValueThanIn(final Identity newIdentity) { - return new Predicate>() { - @Override - public boolean apply(Entry property) { - return (property != null) && !newIdentity.getProperty(property.getKey()).equals(property.getValue()); - } - }; - } - - private static Map convertToMap(Collection identities) { - ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); - for (Identity identity : identities) { - mapBuilder.put(identity.getId(), identity); - } - return mapBuilder.build(); - } - - public interface IdentityProcessor { - - void processIdentity(Identity identity); - - } - -}