package org.warp.commonutils.type; import it.unimi.dsi.fastutil.objects.ObjectSet; import java.util.Optional; import java.util.Set; /** * One to many relationship (not overlapping) * * o ------- o * +--- o * o ---+--- o * +--- o * o ------- o * o ------- o * o ---+--- o * +--- o * * @param Source type * @param Destination type */ public interface Association { /** * Link source to dest * @param src Source * @param dest Destination * @return true if linked, false if it was already linked with that destination */ boolean link(T src, U dest); /** * Unlink only if src is linked with dest * @param src Source * @param dest Destination * @return true if unlinked, false if not present */ boolean unlink(T src, U dest); /** * Unlink * @param src Source * @return previous linked destinations */ Set unlink(T src); /** * Unlink * @param dest Destination * @return previous linked source */ Optional unlinkFromSource(U dest); /** * Check if link exists * @param src Source * @return true if source it's linked with at least 1 destination */ default boolean hasAnyLink(T src) { return !getLinks(src).isEmpty(); } /** * Check if link exists * @param dest Destination * @return true if destination is linked with a source */ default boolean hasLinkSource(U dest) { return getLinkSource(dest).isPresent(); } /** * Check if link exists * @param src Source * @param dest Destination * @return true if source and destination are linked together */ boolean hasLink(T src, U dest); /** * Get a link destination * @param src Source * @return Existing linked destinations */ Set getLinks(T src); /** * Get a link source * @param dest Source * @return Source if the link exists */ Optional getLinkSource(U dest); /** * Delete all links */ void clear(); /** * Get the count of existing links * @return size */ int size(); /** * Get all the sources * @return Set of sources */ ObjectSet getSources(); /** * Get all the destinations * @return Set of destinations */ ObjectSet getDestinations(); static Association synchronize(Association association) { return new SynchronizedAssociation(association); } static Association synchronize(Association association, Object lock) { return new SynchronizedAssociation(association, lock); } }