1 package de.fhdw.wtf.context.model.collections;
2
3 import java.math.BigInteger;
4 import java.util.HashMap;
5 import java.util.Iterator;
6
7 import de.fhdw.wtf.context.core.ObjectFactoryProvider;
8 import de.fhdw.wtf.context.core.TransactionManager;
9 import de.fhdw.wtf.context.exception.FrameworkException;
10 import de.fhdw.wtf.context.model.AnyType;
11 import de.fhdw.wtf.context.model.Anything;
12 import de.fhdw.wtf.context.model.Int;
13 import de.fhdw.wtf.context.model.Str;
14 import de.fhdw.wtf.persistence.meta.MapLink;
15 import de.fhdw.wtf.persistence.meta.Object;
16 import de.fhdw.wtf.persistence.meta.UserObject;
17 import de.fhdw.wtf.persistence.utils.Tuple;
18
19
20
21
22
23
24
25
26
27
28 public class PersistentMapWithKeyValueLinks<K extends Anything, V extends Anything> implements Map<K, V> {
29
30
31
32
33 private final HashMap<K, Tuple<MapLink, V>> mapCache;
34
35
36
37
38 private final String associationName;
39
40
41
42
43 private final UserObject owner;
44
45
46
47
48
49
50
51
52
53 public PersistentMapWithKeyValueLinks(final UserObject owner, final String associationName) {
54 this.owner = owner;
55 this.associationName = associationName;
56 this.mapCache = new HashMap<>();
57 }
58
59 @Override
60 public void put(final K key, final V value) {
61 if (key == null || value == null) {
62 throw new NullPointerException();
63 }
64
65
66 MapLink returnedLink;
67 if (key instanceof Str) {
68 final String castedKeyString = ((Str) key).toString();
69 if (value instanceof Str) {
70 final Str castedValue = (Str) value;
71 returnedLink =
72 TransactionManager.getContext().put(
73 this.owner,
74 this.associationName,
75 castedValue.toString(),
76 castedKeyString);
77 } else if (value instanceof Int) {
78 final Int castedValue = (Int) value;
79 returnedLink =
80 TransactionManager.getContext().put(
81 this.owner,
82 this.associationName,
83 castedValue.getVal(),
84 castedKeyString);
85 } else if (value instanceof AnyType) {
86 final AnyType castedValue = (AnyType) value;
87 returnedLink =
88 TransactionManager.getContext().put(
89 this.owner,
90 this.associationName,
91 castedValue.getObject(),
92 castedKeyString);
93 } else {
94 throw new FrameworkException("Type to insert is not known");
95 }
96 } else if (key instanceof Int) {
97 final BigInteger castedKeyObject = ((Int) key).getVal();
98 if (value instanceof Str) {
99 final Str castedValue = (Str) value;
100 returnedLink =
101 TransactionManager.getContext().put(
102 this.owner,
103 this.associationName,
104 castedValue.toString(),
105 castedKeyObject);
106 } else if (value instanceof Int) {
107 final Int castedValue = (Int) value;
108 returnedLink =
109 TransactionManager.getContext().put(
110 this.owner,
111 this.associationName,
112 castedValue.getVal(),
113 castedKeyObject);
114 } else if (value instanceof AnyType) {
115 final AnyType castedValue = (AnyType) value;
116 returnedLink =
117 TransactionManager.getContext().put(
118 this.owner,
119 this.associationName,
120 castedValue.getObject(),
121 castedKeyObject);
122 } else {
123 throw new FrameworkException("Type to insert is not known");
124 }
125 } else if (key instanceof AnyType) {
126 final UserObject castedKeyObject = ((AnyType) key).getObject();
127 if (value instanceof Str) {
128 final Str castedValue = (Str) value;
129 returnedLink =
130 TransactionManager.getContext().put(
131 this.owner,
132 this.associationName,
133 castedValue.toString(),
134 castedKeyObject);
135 } else if (value instanceof Int) {
136 final Int castedValue = (Int) value;
137 returnedLink =
138 TransactionManager.getContext().put(
139 this.owner,
140 this.associationName,
141 castedValue.getVal(),
142 castedKeyObject);
143 } else if (value instanceof AnyType) {
144 final AnyType castedValue = (AnyType) value;
145 returnedLink =
146 TransactionManager.getContext().put(
147 this.owner,
148 this.associationName,
149 castedValue.getObject(),
150 castedKeyObject);
151 } else {
152 throw new FrameworkException("Type to insert is not known");
153 }
154 } else {
155 throw new FrameworkException("Type to insert is not known");
156 }
157
158 this.mapCache.put(key, new Tuple<>(returnedLink, value));
159 }
160
161 @Override
162 public V get(final K key) {
163 if (key == null) {
164 throw new NullPointerException();
165 }
166
167
168 if (this.mapCache.containsKey(key)) {
169 return this.getFromCache(key);
170 } else {
171 java.util.Collection<Tuple<MapLink, Object>> databaseResult = null;
172 if (key instanceof Str) {
173 databaseResult =
174 TransactionManager.getContext().get(this.owner, this.associationName, ((Str) key).toString());
175 } else if (key instanceof Int) {
176 databaseResult =
177 TransactionManager.getContext().get(this.owner, this.associationName, ((Int) key).getVal());
178 } else if (key instanceof AnyType) {
179 databaseResult =
180 TransactionManager.getContext().get(
181 this.owner,
182 this.associationName,
183 ((AnyType) key).getObject());
184 } else {
185 throw new FrameworkException("Type to insert is not known");
186 }
187 final Iterator<Tuple<MapLink, Object>> iterator = databaseResult.iterator();
188
189 if (!iterator.hasNext()) {
190 this.mapCache.put(key, null);
191 return null;
192 }
193
194 final Tuple<MapLink, Object> firstResult = iterator.next();
195 final Object firstResultTarget = firstResult.getSecond();
196 @SuppressWarnings("unchecked")
197 final V result = (V) ObjectFactoryProvider.instance().createObject(firstResultTarget);
198 this.mapCache.put(key, new Tuple<>(firstResult.getFirst(), result));
199 return this.getFromCache(key);
200 }
201 }
202
203
204
205
206
207
208
209
210 private V getFromCache(final K key) {
211 final Tuple<MapLink, V> localTupel = this.mapCache.get(key);
212 if (localTupel == null) {
213 return null;
214 }
215 return localTupel.getSecond();
216 }
217
218 @Override
219 public V remove(final K key) {
220 if (key == null) {
221 throw new NullPointerException();
222 }
223 final Tuple<MapLink, V> toRemoveTuple = this.mapCache.get(key);
224
225 TransactionManager.getContext().unset(toRemoveTuple.getFirst());
226
227 this.mapCache.put(key, null);
228 return toRemoveTuple.getSecond();
229 }
230
231
232
233
234
235
236
237
238
239 }