package turin.relations; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public class ManyToManyRelation<A, B> implements Relation<A,B> { private Map<A, List<B>> byEndpointA = new HashMap<>(); private Map<B, List<A>> byEndpointB = new HashMap<>(); private Map<A, Subset> aSubsets = new HashMap<>(); private Map<B, Subset> bSubsets = new HashMap<>(); public Subset newASubset() { return new Subset(); } public Subset newBSubset() { return new Subset(); } @Override public void link(A endpointA, B endpointB) { if (areLinked(endpointA, endpointB)) { return; } if (!byEndpointA.containsKey(endpointA)) { byEndpointA.put(endpointA, new LinkedList<B>()); } if (!byEndpointB.containsKey(endpointB)) { byEndpointB.put(endpointB, new LinkedList<A>()); } byEndpointA.get(endpointA).add(endpointB); byEndpointB.get(endpointB).add(endpointA); } @Override public void unlink(Object professor, Object course) { byEndpointA.get(professor).remove(course); byEndpointB.get(course).remove(professor); } @Override public boolean areLinked(Object a, Object b) { if (byEndpointB.containsKey(b)) { return byEndpointB.get(b).contains(a); } else { return false; } } public ReferenceMultipleEndpoint getReferenceForB(B b) { return new ReferenceMultipleEndpoint(b, byEndpointB, this); } public ReferenceMultipleEndpoint getReferenceForA(A a) { return new ReferenceMultipleEndpoint(a, byEndpointA, this); } public ReferenceMultipleEndpoint getReferenceForA(A a, Subset subset) { return new ReferenceMultipleEndpoint(a, byEndpointA, this, bSubsets, subset); } public ReferenceMultipleEndpoint getReferenceForB(B b, Subset subset) { return new ReferenceMultipleEndpoint(b, byEndpointB, this, aSubsets, subset); } }