1 package org.csc.phynixx.common.utils;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import java.util.*;
25
26
27
28
29 public class UnorderedMany2ManyAssociation<X, Y> {
30
31 final Map<X, Set<Y>> mapA = new HashMap<X, Set<Y>>();
32
33 final Map<Y, Set<X>> mapB = new HashMap<Y, Set<X>>();
34
35
36 public void associate(X x, Y y) {
37 assertSet(mapA, x).add(y);
38 assertSet(mapB, y).add(x);
39 }
40
41
42 public Set<Y> getX(X x) {
43 return getEndpoints(x, mapA);
44 }
45
46 public Set<X> getY(Y y) {
47 return getEndpoints(y, mapB);
48 }
49
50
51 public void removeX(X x) {
52 removeDependents(x, mapA, mapB);
53 mapA.remove(x);
54 }
55
56
57 public void removeY(Y y) {
58 removeDependents(y, mapB, mapA);
59 mapB.remove(y);
60 }
61
62
63 public void disassociate(X x, Y y) {
64 removeDependent(x, y, mapA);
65 removeDependent(y, x, mapB);
66 }
67
68
69 static <K, V> Set<V> getEndpoints(K k, Map<K, Set<V>> map) {
70 Set<V> value = map.get(k);
71 if (value == null) {
72 return Collections.emptySet();
73 }
74 return Collections.unmodifiableSet(value);
75 }
76
77
78 static <K, V> void removeDependents(K key, Map<K, Set<V>> map, Map<V, Set<K>> inverseMap) {
79 Set<V> value = map.get(key);
80 if (value != null && !value.isEmpty()) {
81 for (V v : value) {
82 Set<K> keys = inverseMap.get(v);
83 if (keys != null && !keys.isEmpty()) {
84 keys.remove(key);
85 }
86 }
87 }
88 }
89
90 static <K, V> void removeDependent(K k, V v, Map<K, Set<V>> map) {
91 Set<V> value = map.get(k);
92 if (value != null && !value.isEmpty()) {
93 value.remove(v);
94 }
95 }
96
97
98 static <K, V> Set<V> assertSet(Map<K, Set<V>> map, K key) {
99 Set<V> value = map.get(key);
100 if (value == null) {
101 value = new HashSet<V>();
102 map.put(key, value);
103 }
104 return value;
105 }
106
107
108 }