1 package de.fhdw.wtf.persistence.facade;
2
3 import java.math.BigInteger;
4 import java.sql.SQLException;
5 import java.util.Collection;
6 import java.util.Date;
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.Iterator;
10 import java.util.LinkedList;
11 import java.util.Map;
12 import java.util.regex.Matcher;
13 import java.util.regex.Pattern;
14
15 import de.fhdw.wtf.persistence.exception.BaseTypeNotFoundException;
16 import de.fhdw.wtf.persistence.exception.InvalidLinkException;
17 import de.fhdw.wtf.persistence.exception.NotInstantiatableException;
18 import de.fhdw.wtf.persistence.exception.NotValidInputException;
19 import de.fhdw.wtf.persistence.exception.ObjectNotFoundException;
20 import de.fhdw.wtf.persistence.exception.PersistenceException;
21 import de.fhdw.wtf.persistence.meta.AdhocTransaction;
22 import de.fhdw.wtf.persistence.meta.Association;
23 import de.fhdw.wtf.persistence.meta.IntegerType;
24 import de.fhdw.wtf.persistence.meta.IntegerValue;
25 import de.fhdw.wtf.persistence.meta.Link;
26 import de.fhdw.wtf.persistence.meta.MapAssociation;
27 import de.fhdw.wtf.persistence.meta.MapLink;
28 import de.fhdw.wtf.persistence.meta.Object;
29 import de.fhdw.wtf.persistence.meta.StringType;
30 import de.fhdw.wtf.persistence.meta.StringValue;
31 import de.fhdw.wtf.persistence.meta.Transaction;
32 import de.fhdw.wtf.persistence.meta.Type;
33 import de.fhdw.wtf.persistence.meta.UnidirectionalAssociation;
34 import de.fhdw.wtf.persistence.meta.UnidirectionalLink;
35 import de.fhdw.wtf.persistence.meta.UserObject;
36 import de.fhdw.wtf.persistence.meta.UserType;
37 import de.fhdw.wtf.persistence.utils.Tuple;
38
39
40
41
42
43
44
45 public class NoDatabaseObjectFacadeImplementation implements ObjectFacade {
46
47
48
49
50
51 private static final long INITIAL_NEXT_ID = 1;
52
53
54
55
56 private final ClassFacade classFacade;
57
58
59
60
61 private long nextId;
62
63
64
65
66 private final Map<Long, UserObject> idToUserObject;
67
68
69
70
71 private final Map<UserType, Collection<UserObject>> userTypeMappingToUserObjects;
72
73
74
75
76 private final Map<Long, BigInteger> integerValues;
77
78
79
80
81 private final Map<BigInteger, Long> inverseIntegerValues;
82
83
84
85
86 private final Map<Long, String> stringValues;
87
88
89
90
91 private final Map<String, Long> inverseStringValues;
92
93
94
95
96
97 private final Map<Object, Collection<Tuple<UnidirectionalLink, UserObject>>> targetMappingToUnidirectionalLinksWithOwners;
98
99
100
101
102
103 private final Map<UserObject, Collection<Tuple<UnidirectionalLink, Object>>> ownerMappingToUnidirectionalLinksWithTargets;
104
105
106
107
108
109 private final HashMap<UserObject, Collection<MapLink>> ownerMappingToMapLinks;
110
111
112
113
114
115 private final HashMap<Object, Collection<MapLink>> targetMappingToMapLinks;
116
117
118
119
120
121 private final HashMap<UnidirectionalAssociation, Collection<Tuple<UserObject, StringValue>>> associationToStringValue;
122
123
124
125
126
127 private final HashMap<UnidirectionalAssociation, Collection<Tuple<UserObject, IntegerValue>>> associationToIntegerValue;
128
129
130
131
132
133
134
135
136 public NoDatabaseObjectFacadeImplementation(final ClassFacade classFacade) {
137 super();
138 IntegerValue.setObjectFacade(this);
139 StringValue.setObjectFacade(this);
140 this.classFacade = classFacade;
141 this.nextId = NoDatabaseObjectFacadeImplementation.INITIAL_NEXT_ID;
142 this.userTypeMappingToUserObjects = new HashMap<>();
143 this.integerValues = new HashMap<>();
144 this.stringValues = new HashMap<>();
145 this.inverseIntegerValues = new HashMap<>();
146 this.inverseStringValues = new HashMap<>();
147 this.idToUserObject = new HashMap<>();
148 this.targetMappingToUnidirectionalLinksWithOwners = new HashMap<>();
149 this.ownerMappingToUnidirectionalLinksWithTargets = new HashMap<>();
150 this.ownerMappingToMapLinks = new HashMap<>();
151 this.targetMappingToMapLinks = new HashMap<>();
152 this.associationToStringValue = new HashMap<>();
153 this.associationToIntegerValue = new HashMap<>();
154 }
155
156 @Override
157 public void clear() throws PersistenceException {
158 this.nextId = NoDatabaseObjectFacadeImplementation.INITIAL_NEXT_ID;
159 this.userTypeMappingToUserObjects.clear();
160 this.integerValues.clear();
161 this.stringValues.clear();
162 this.inverseIntegerValues.clear();
163 this.inverseStringValues.clear();
164 this.idToUserObject.clear();
165 this.ownerMappingToUnidirectionalLinksWithTargets.clear();
166 this.targetMappingToUnidirectionalLinksWithOwners.clear();
167 this.ownerMappingToMapLinks.clear();
168 this.targetMappingToMapLinks.clear();
169 this.associationToStringValue.clear();
170 this.associationToIntegerValue.clear();
171 }
172
173 @Override
174 public Collection<UserObject> find(final Association association, final String searchPatternOracle, final Date date)
175 throws PersistenceException {
176
177
178
179
180 final String searchPatternRegex = searchPatternOracle.replaceAll("\\*", "\\\\*").replaceAll("%+", ".*");
181 final Pattern searchPattern = Pattern.compile(searchPatternRegex);
182
183 final HashSet<UserObject> result = new HashSet<>();
184 if (!this.associationToStringValue.containsKey(association)) {
185 return result;
186 }
187
188 final Iterator<Tuple<UserObject, StringValue>> it = this.associationToStringValue.get(association).iterator();
189 while (it.hasNext()) {
190 final Tuple<UserObject, StringValue> current = it.next();
191 final String target = current.getSecond().getValue();
192
193 final Matcher targetSearchMatcher = searchPattern.matcher(target);
194 if (targetSearchMatcher.matches()) {
195 result.add(current.getFirst());
196 }
197 }
198 return result;
199 }
200
201 @Override
202 public Collection<UserObject> find(final Association association, final BigInteger integer, final Date date)
203 throws PersistenceException {
204 final HashSet<UserObject> result = new HashSet<>();
205 if (!this.associationToIntegerValue.containsKey(association)) {
206 return result;
207 }
208
209 final Iterator<Tuple<UserObject, IntegerValue>> it = this.associationToIntegerValue.get(association).iterator();
210 while (it.hasNext()) {
211 final Tuple<UserObject, IntegerValue> current = it.next();
212 final BigInteger target = current.getSecond().getValue();
213 if (integer.equals(target)) {
214 result.add(current.getFirst());
215 }
216 }
217 return result;
218 }
219
220 @Override
221 public Collection<Tuple<UnidirectionalLink, Object>> get(final UserObject owner,
222 final UnidirectionalAssociation association,
223 final Date date) throws PersistenceException {
224 return this.get(owner, association);
225 }
226
227 @Override
228 public Collection<Object> get(final UserObject owner,
229 final MapAssociation association,
230 final String key,
231 final Date date) throws PersistenceException {
232 final Collection<Object> result = new LinkedList<>();
233 if (!this.ownerMappingToMapLinks.containsKey(owner)) {
234 return result;
235 }
236 final Iterator<MapLink> it = this.ownerMappingToMapLinks.get(owner).iterator();
237 while (it.hasNext()) {
238 final MapLink currentMapLink = it.next();
239 if (currentMapLink.getInstanceOf().equals(association) && currentMapLink.getKey() instanceof StringValue) {
240 if (((StringValue) currentMapLink.getKey()).getValue().equals(key)) {
241 result.add(currentMapLink.getTarget());
242 }
243 }
244 }
245 if (result.isEmpty()) {
246 throw new ObjectNotFoundException();
247 }
248 return result;
249 }
250
251 @Override
252 public Collection<Object> get(final UserObject owner,
253 final MapAssociation association,
254 final BigInteger key,
255 final Date date) throws PersistenceException {
256 final Collection<Object> result = new LinkedList<>();
257 if (!this.ownerMappingToMapLinks.containsKey(owner)) {
258 return result;
259 }
260 final Iterator<MapLink> it = this.ownerMappingToMapLinks.get(owner).iterator();
261 while (it.hasNext()) {
262 final MapLink currentMapLink = it.next();
263 if (currentMapLink.getInstanceOf().equals(association) && currentMapLink.getKey() instanceof IntegerValue) {
264 if (((IntegerValue) currentMapLink.getKey()).getValue().equals(key)) {
265 result.add(currentMapLink.getTarget());
266 }
267 }
268 }
269 if (result.isEmpty()) {
270 throw new ObjectNotFoundException();
271 }
272 return result;
273 }
274
275 @Override
276 public Collection<Object> get(final UserObject owner,
277 final MapAssociation association,
278 final UserObject key,
279 final Date date) throws PersistenceException {
280 if (key == null) {
281 throw new NotValidInputException("");
282 }
283 final Collection<Object> result = new LinkedList<>();
284 if (!this.ownerMappingToMapLinks.containsKey(owner)) {
285 return result;
286 }
287 final Iterator<MapLink> it = this.ownerMappingToMapLinks.get(owner).iterator();
288 while (it.hasNext()) {
289 final MapLink currentMapLink = it.next();
290 if (currentMapLink.getInstanceOf().equals(association) && currentMapLink.getKey() instanceof UserObject) {
291 if (currentMapLink.getKey().equals(key)) {
292 result.add(currentMapLink.getTarget());
293 }
294 }
295 }
296 if (result.isEmpty()) {
297 throw new ObjectNotFoundException();
298 }
299 return result;
300 }
301
302 @Override
303 public Collection<Tuple<UnidirectionalLink, UserObject>> inverseGet(final UserObject target,
304 final UnidirectionalAssociation association,
305 final Date date) throws PersistenceException {
306 return this.inverseGet(target, association);
307 }
308
309 @Override
310 public Collection<Tuple<UserObject, Object>> inverseGet(final UserObject target,
311 final MapAssociation association,
312 final Date date) throws PersistenceException {
313 final Collection<Tuple<UserObject, Object>> result = new LinkedList<>();
314 if (!this.targetMappingToMapLinks.containsKey(target)) {
315 return result;
316 }
317 final Iterator<MapLink> it = this.targetMappingToMapLinks.get(target).iterator();
318 while (it.hasNext()) {
319 final MapLink currentMapLink = it.next();
320 if (currentMapLink.getInstanceOf().equals(association)) {
321 result.add(new Tuple<>(currentMapLink.getOwner(), currentMapLink.getKey()));
322 }
323 }
324 return result;
325 }
326
327 @Override
328 public Collection<Tuple<UserObject, Object>> inverseGet(final String target,
329 final MapAssociation association,
330 final Date date) throws PersistenceException {
331 final Collection<Tuple<UserObject, Object>> result = new LinkedList<>();
332 final Iterator<Object> itMain = this.targetMappingToMapLinks.keySet().iterator();
333 while (itMain.hasNext()) {
334 final Object ob = itMain.next();
335 if (!(ob instanceof StringValue)) {
336 continue;
337 }
338 final StringValue val = (StringValue) ob;
339 if (!val.getValue().equals(target)) {
340 continue;
341 }
342 final Iterator<MapLink> it = this.targetMappingToMapLinks.get(val).iterator();
343 while (it.hasNext()) {
344 final MapLink currentMapLink = it.next();
345 if (currentMapLink.getInstanceOf().equals(association)) {
346 result.add(new Tuple<>(currentMapLink.getOwner(), currentMapLink.getKey()));
347 }
348 }
349 }
350 return result;
351 }
352
353 @Override
354 public Collection<Tuple<UserObject, Object>> inverseGet(final BigInteger target,
355 final MapAssociation association,
356 final Date date) throws PersistenceException {
357 final Collection<Tuple<UserObject, Object>> result = new LinkedList<>();
358 final Iterator<Object> itMain = this.targetMappingToMapLinks.keySet().iterator();
359 while (itMain.hasNext()) {
360 final Object ob = itMain.next();
361 if (!(ob instanceof IntegerValue)) {
362 continue;
363 }
364 final IntegerValue val = (IntegerValue) ob;
365 if (!val.getValue().equals(target)) {
366 continue;
367 }
368 final Iterator<MapLink> it = this.targetMappingToMapLinks.get(val).iterator();
369 while (it.hasNext()) {
370 final MapLink currentMapLink = it.next();
371 if (currentMapLink.getInstanceOf().equals(association)) {
372 result.add(new Tuple<>(currentMapLink.getOwner(), currentMapLink.getKey()));
373 }
374 }
375 }
376 return result;
377 }
378
379 @Override
380 public Collection<UserObject> find(final Association assoc, final String str, final Transaction trans)
381 throws PersistenceException {
382 return this.find(assoc, str, new Date());
383 }
384
385 @Override
386 public Collection<UserObject> find(final Association association,
387 final BigInteger integer,
388 final Transaction transaction) throws PersistenceException {
389 return this.find(association, integer, new Date());
390 }
391
392 @Override
393 public Collection<Tuple<UnidirectionalLink, Object>> get(final UserObject owner,
394 final UnidirectionalAssociation association,
395 final Transaction transaction) throws PersistenceException {
396 return this.get(owner, association);
397 }
398
399
400
401
402
403
404
405
406
407
408
409
410 private Collection<Tuple<UnidirectionalLink, Object>> get(final UserObject owner,
411 final UnidirectionalAssociation association) {
412 final Collection<Tuple<UnidirectionalLink, Object>> result = new LinkedList<>();
413 if (!this.ownerMappingToUnidirectionalLinksWithTargets.containsKey(owner)) {
414 return result;
415 }
416 final Iterator<Tuple<UnidirectionalLink, Object>> allLinksForOwner =
417 this.ownerMappingToUnidirectionalLinksWithTargets.get(owner).iterator();
418 while (allLinksForOwner.hasNext()) {
419 final Tuple<UnidirectionalLink, Object> currentTuple = allLinksForOwner.next();
420 if (currentTuple.getFirst().getInstanceOf().equals(association)) {
421 result.add(currentTuple);
422 }
423 }
424 return result;
425 }
426
427 @Override
428 public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
429 final MapAssociation association,
430 final String key,
431 final Transaction transaction) throws PersistenceException {
432 final Collection<Tuple<MapLink, Object>> result = new HashSet<>();
433 if (!this.ownerMappingToMapLinks.containsKey(owner)) {
434 throw new ObjectNotFoundException();
435 }
436 final Iterator<MapLink> it = this.ownerMappingToMapLinks.get(owner).iterator();
437 while (it.hasNext()) {
438 final MapLink currentMapLink = it.next();
439 if (currentMapLink.getInstanceOf().equals(association)) {
440 if (((StringValue) currentMapLink.getKey()).getValue().equals(key)) {
441 result.add(new Tuple<>(currentMapLink, currentMapLink.getTarget()));
442 }
443 }
444 }
445 if (result.isEmpty()) {
446 throw new ObjectNotFoundException();
447 }
448 return result;
449 }
450
451 @Override
452 public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
453 final MapAssociation association,
454 final BigInteger key,
455 final Transaction transaction) throws PersistenceException {
456 final Collection<Tuple<MapLink, Object>> result = new HashSet<>();
457 if (!this.ownerMappingToMapLinks.containsKey(owner)) {
458 return result;
459 }
460 final Iterator<MapLink> it = this.ownerMappingToMapLinks.get(owner).iterator();
461 while (it.hasNext()) {
462 final MapLink currentMapLink = it.next();
463 if (currentMapLink.getInstanceOf().equals(association)) {
464 if (((IntegerValue) currentMapLink.getKey()).getValue().equals(key)) {
465 result.add(new Tuple<>(currentMapLink, currentMapLink.getTarget()));
466 }
467 }
468 }
469 return result;
470 }
471
472 @Override
473 public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
474 final MapAssociation association,
475 final UserObject key,
476 final Transaction transaction) throws PersistenceException {
477 if (key == null) {
478 throw new NotValidInputException("");
479 }
480 final Collection<Tuple<MapLink, Object>> result = new HashSet<>();
481 if (!this.ownerMappingToMapLinks.containsKey(owner)) {
482 return result;
483 }
484 final Iterator<MapLink> it = this.ownerMappingToMapLinks.get(owner).iterator();
485 while (it.hasNext()) {
486 final MapLink currentMapLink = it.next();
487 if (currentMapLink.getInstanceOf().equals(association)) {
488 if (currentMapLink.getKey().equals(key)) {
489 result.add(new Tuple<>(currentMapLink, currentMapLink.getTarget()));
490 }
491 }
492 }
493 return result;
494 }
495
496 @Override
497 public Collection<Tuple<UnidirectionalLink, UserObject>> inverseGet(final UserObject target,
498 final UnidirectionalAssociation association,
499 final Transaction transaction) throws PersistenceException {
500 return this.inverseGet(target, association);
501 }
502
503
504
505
506
507
508
509
510
511
512
513
514
515 private Collection<Tuple<UnidirectionalLink, UserObject>> inverseGet(final UserObject target,
516 final UnidirectionalAssociation association) {
517 final Collection<Tuple<UnidirectionalLink, UserObject>> result = new LinkedList<>();
518 if (!this.targetMappingToUnidirectionalLinksWithOwners.containsKey(target)) {
519 return result;
520 }
521 final Iterator<Tuple<UnidirectionalLink, UserObject>> allLinksForTarget =
522 this.targetMappingToUnidirectionalLinksWithOwners.get(target).iterator();
523 while (allLinksForTarget.hasNext()) {
524 final Tuple<UnidirectionalLink, UserObject> currentTuple = allLinksForTarget.next();
525 if (currentTuple.getFirst().getInstanceOf().equals(association)) {
526 result.add(currentTuple);
527 }
528 }
529 return result;
530 }
531
532 @Override
533 public Collection<Tuple<UserObject, Object>> inverseGet(final UserObject target,
534 final MapAssociation association,
535 final Transaction transaction) throws PersistenceException {
536 return this.inverseGet(target, association, new Date());
537 }
538
539 @Override
540 public Collection<Tuple<UserObject, Object>> inverseGet(final String target,
541 final MapAssociation association,
542 final Transaction transaction) throws PersistenceException {
543 return this.inverseGet(target, association, new Date());
544 }
545
546 @Override
547 public Collection<Tuple<UserObject, Object>> inverseGet(final BigInteger target,
548 final MapAssociation association,
549 final Transaction transaction) throws PersistenceException {
550 return this.inverseGet(target, association, new Date());
551 }
552
553 @Override
554 public boolean isInConflict(final Transaction before, final Transaction after) throws PersistenceException {
555
556 return false;
557 }
558
559 @Override
560 public boolean isOpenTransaction(final Transaction transaction) throws PersistenceException {
561
562 return true;
563 }
564
565 @Override
566 public UserObject create(final UserType type, final Transaction transaction) throws PersistenceException {
567 if (type.isAbs()) {
568 throw new NotInstantiatableException(new SQLException());
569 }
570 final UserObject result = UserObject.init(this.getAndIncrementNextId(), type);
571 this.idToUserObject.put(result.getId(), result);
572 this.mapUserTypeToEmptyListIfNotExists(type);
573 this.userTypeMappingToUserObjects.get(type).add(result);
574 return result;
575 }
576
577 @Override
578 public void delete(final UserObject object, final Transaction transaction) throws PersistenceException {
579
580 this.idToUserObject.remove(object.getId());
581
582
583 this.userTypeMappingToUserObjects.get(object.getInstanceOf()).remove(object);
584
585
586 this.ownerMappingToUnidirectionalLinksWithTargets.remove(object);
587
588
589 this.targetMappingToUnidirectionalLinksWithOwners.remove(object);
590
591
592 this.ownerMappingToMapLinks.remove(object);
593
594
595 this.targetMappingToMapLinks.remove(object);
596
597 this.deleteFromFindMap(object.getInstanceOf(), object.getId());
598 }
599
600 private void deleteFromFindMap(final Type type, final long id) throws PersistenceException {
601
602
603 }
604
605 @Override
606 public UnidirectionalLink set(final UserObject owner,
607 final UnidirectionalAssociation association,
608 final UserObject target,
609 final Transaction transaction) throws PersistenceException {
610 this.checkAssociationUnidirectional(association, owner.getInstanceOf(), target.getInstanceOf());
611 return this.set(owner, association, target);
612 }
613
614 @Override
615 public UnidirectionalLink set(final UserObject owner,
616 final UnidirectionalAssociation association,
617 final BigInteger target,
618 final Transaction transaction) throws PersistenceException {
619 this.checkAssociationUnidirectional(association, owner.getInstanceOf(), IntegerType.getInstance());
620 return this.set(owner, association, new IntegerValue(target));
621 }
622
623 @Override
624 public UnidirectionalLink set(final UserObject owner,
625 final UnidirectionalAssociation association,
626 final String target,
627 final Transaction transaction) throws PersistenceException {
628 this.checkAssociationUnidirectional(association, owner.getInstanceOf(), StringType.getInstance());
629 return this.set(owner, association, new StringValue(target));
630 }
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648 private UnidirectionalLink set(final UserObject owner,
649 final UnidirectionalAssociation association,
650 final Object target) throws PersistenceException {
651 this.throwInvalidLinkExceptionIfWrongTypeForLink(owner, association, target);
652 final UnidirectionalLink result =
653 new UnidirectionalLink(this.getAndIncrementNextId(), owner, target, association);
654 final Tuple<UnidirectionalLink, Object> tupleForOwner = new Tuple<>(result, target);
655 if (!this.ownerMappingToUnidirectionalLinksWithTargets.containsKey(owner)) {
656 this.ownerMappingToUnidirectionalLinksWithTargets.put(
657 owner,
658 new LinkedList<Tuple<UnidirectionalLink, Object>>());
659 }
660 final Tuple<UnidirectionalLink, UserObject> tupleForTarget = new Tuple<>(result, owner);
661 if (!this.targetMappingToUnidirectionalLinksWithOwners.containsKey(target)) {
662 this.targetMappingToUnidirectionalLinksWithOwners.put(
663 target,
664 new LinkedList<Tuple<UnidirectionalLink, UserObject>>());
665 }
666 if (association.isUnique()) {
667 this.deleteAllOwnerUnidirectionalLinksWhichAreInstanceOf(owner, association);
668 this.deleteAllTargetUnidirectionalLinksWhichAreInstanceOf(target, association);
669 }
670 this.ownerMappingToUnidirectionalLinksWithTargets.get(owner).add(tupleForOwner);
671 this.targetMappingToUnidirectionalLinksWithOwners.get(target).add(tupleForTarget);
672
673
674 if (target instanceof StringValue) {
675 if (!this.associationToStringValue.containsKey(association)) {
676 this.associationToStringValue.put(association, new LinkedList<Tuple<UserObject, StringValue>>());
677 }
678 this.associationToStringValue.get(association).add(new Tuple<>(owner, (StringValue) target));
679 }
680 if (target instanceof IntegerValue) {
681 if (!this.associationToIntegerValue.containsKey(association)) {
682 this.associationToIntegerValue.put(association, new LinkedList<Tuple<UserObject, IntegerValue>>());
683 }
684 this.associationToIntegerValue.get(association).add(new Tuple<>(owner, (IntegerValue) target));
685 }
686
687 return result;
688 }
689
690
691
692
693
694
695
696
697
698
699 private void deleteAllTargetUnidirectionalLinksWhichAreInstanceOf(final Object target,
700 final UnidirectionalAssociation association) {
701 if (this.targetMappingToUnidirectionalLinksWithOwners.containsKey(target)) {
702 final Iterator<Tuple<UnidirectionalLink, UserObject>> allLinks =
703 this.targetMappingToUnidirectionalLinksWithOwners.get(target).iterator();
704 while (allLinks.hasNext()) {
705 if (allLinks.next().getFirst().getInstanceOf().equals(association)) {
706 allLinks.remove();
707 }
708 }
709 }
710 }
711
712
713
714
715
716
717
718
719
720
721 private void deleteAllOwnerUnidirectionalLinksWhichAreInstanceOf(final UserObject owner,
722 final UnidirectionalAssociation association) {
723 if (this.ownerMappingToUnidirectionalLinksWithTargets.containsKey(owner)) {
724 final Iterator<Tuple<UnidirectionalLink, Object>> allLinks =
725 this.ownerMappingToUnidirectionalLinksWithTargets.get(owner).iterator();
726 while (allLinks.hasNext()) {
727 if (allLinks.next().getFirst().getInstanceOf().equals(association)) {
728 allLinks.remove();
729 }
730 }
731 }
732 }
733
734 @Override
735 public MapLink put(final UserObject owner,
736 final MapAssociation association,
737 final UserObject target,
738 final String key,
739 final Transaction transaction) throws PersistenceException {
740 return this.putInternal(owner, association, target, new StringValue(key));
741 }
742
743 @Override
744 public MapLink put(final UserObject owner,
745 final MapAssociation association,
746 final BigInteger target,
747 final String key,
748 final Transaction transaction) throws PersistenceException {
749 return this.putInternal(owner, association, new IntegerValue(target), new StringValue(key));
750 }
751
752 @Override
753 public MapLink put(final UserObject owner,
754 final MapAssociation association,
755 final String target,
756 final String key,
757 final Transaction transaction) throws PersistenceException {
758 return this.putInternal(owner, association, new StringValue(target), new StringValue(key));
759 }
760
761 @Override
762 public MapLink put(final UserObject owner,
763 final MapAssociation association,
764 final UserObject target,
765 final BigInteger key,
766 final Transaction transaction) throws PersistenceException {
767 return this.putInternal(owner, association, target, new IntegerValue(key));
768 }
769
770 @Override
771 public MapLink put(final UserObject owner,
772 final MapAssociation association,
773 final BigInteger target,
774 final BigInteger key,
775 final Transaction transaction) throws PersistenceException {
776 return this.putInternal(owner, association, new IntegerValue(target), new IntegerValue(key));
777 }
778
779 @Override
780 public MapLink put(final UserObject owner,
781 final MapAssociation association,
782 final String target,
783 final BigInteger key,
784 final Transaction transaction) throws PersistenceException {
785 return this.putInternal(owner, association, new StringValue(target), new IntegerValue(key));
786 }
787
788 @Override
789 public MapLink put(final UserObject owner,
790 final MapAssociation association,
791 final UserObject target,
792 final UserObject key,
793 final Transaction transaction) throws PersistenceException {
794 return this.putInternal(owner, association, target, key);
795 }
796
797 @Override
798 public MapLink put(final UserObject owner,
799 final MapAssociation association,
800 final BigInteger target,
801 final UserObject key,
802 final Transaction transaction) throws PersistenceException {
803 return this.putInternal(owner, association, new IntegerValue(target), key);
804 }
805
806 @Override
807 public MapLink put(final UserObject owner,
808 final MapAssociation association,
809 final String target,
810 final UserObject key,
811 final Transaction transaction) throws PersistenceException {
812 return this.putInternal(owner, association, new StringValue(target), key);
813 }
814
815 private MapLink putInternal(final UserObject owner,
816 final MapAssociation association,
817 final Object target,
818 final Object key) throws PersistenceException {
819 this.checkAssociationMap(association, owner.getInstanceOf(), target.getInstanceOf(), key.getInstanceOf());
820
821 if (!this.ownerMappingToMapLinks.containsKey(owner)) {
822 this.ownerMappingToMapLinks.put(owner, new LinkedList<MapLink>());
823 }
824 if (!this.targetMappingToMapLinks.containsKey(target)) {
825 this.targetMappingToMapLinks.put(target, new LinkedList<MapLink>());
826 }
827
828
829
830 final MapLink result = new MapLink(this.getAndIncrementNextId(), owner, target, key, association);
831
832 this.ownerMappingToMapLinks.get(owner).add(result);
833 this.targetMappingToMapLinks.get(target).add(result);
834
835 return result;
836 }
837
838 @Override
839 public void unset(final Link link, final Transaction transaction) throws PersistenceException {
840
841 }
842
843 @Override
844 public void commit(final Transaction transaction) throws PersistenceException {
845
846 }
847
848 @Override
849 public void rollback(final Transaction transaction) throws PersistenceException {
850
851 }
852
853 @Override
854 public void savePoint(final Transaction transaction) throws PersistenceException {
855
856 }
857
858 @Override
859 public void rollbackToSavePoint(final Transaction transaction) throws PersistenceException {
860
861 }
862
863 @Override
864 public BigInteger getIntForId(final long id) throws PersistenceException {
865 if (!this.integerValues.containsKey(id)) {
866 throw new BaseTypeNotFoundException();
867 }
868 return this.integerValues.get(id);
869 }
870
871 @Override
872 public String getStringForId(final long id) throws PersistenceException {
873 if (!this.stringValues.containsKey(id)) {
874 throw new BaseTypeNotFoundException();
875 }
876 return this.stringValues.get(id);
877 }
878
879 @Override
880 public long getIdForString(final String string) throws PersistenceException {
881 if (!this.inverseStringValues.containsKey(string)) {
882 final long newId = this.getAndIncrementNextId();
883 this.stringValues.put(newId, string);
884 this.inverseStringValues.put(string, newId);
885 }
886 return this.inverseStringValues.get(string);
887 }
888
889 @Override
890 public long getIdForInteger(final BigInteger integer) throws PersistenceException {
891 if (!this.inverseIntegerValues.containsKey(integer)) {
892 final long newId = this.getAndIncrementNextId();
893 this.integerValues.put(newId, integer);
894 this.inverseIntegerValues.put(integer, newId);
895 }
896 return this.inverseIntegerValues.get(integer);
897 }
898
899 @Override
900 public Transaction provideAdhocTransaction() throws PersistenceException {
901 return new AdhocTransaction(this.getAndIncrementNextId());
902 }
903
904 @Override
905 public TypeManager getTypeManager() {
906 return TypeManagerImplementation.getInstance();
907 }
908
909 @Override
910 public Collection<UserObject> findAllObjects(final UserType type, final Transaction transaction)
911 throws PersistenceException {
912 this.mapUserTypeToEmptyListIfNotExists(type);
913 return this.userTypeMappingToUserObjects.get(type);
914 }
915
916 @Override
917 public UserObject checkUserObjectOut(final long id, final Transaction transaction) throws PersistenceException {
918 if (!this.idToUserObject.containsKey(id)) {
919 throw new ObjectNotFoundException();
920 }
921 return this.idToUserObject.get(id);
922 }
923
924
925
926
927
928
929
930
931 private void mapUserTypeToEmptyListIfNotExists(final UserType type) {
932 if (!this.userTypeMappingToUserObjects.containsKey(type)) {
933 this.userTypeMappingToUserObjects.put(type, new LinkedList<UserObject>());
934 }
935 }
936
937
938
939
940 private long getAndIncrementNextId() {
941 final long result = this.nextId;
942 this.nextId++;
943 return result;
944 }
945
946
947
948
949
950
951
952
953
954
955
956
957
958 private void checkAssociationUnidirectional(final UnidirectionalAssociation association,
959 final Type owner,
960 final Type target) throws PersistenceException {
961 if (!association.getOwner().isTheSameAs(owner)
962 && !this.classFacade.isSuperClassTo(association.getOwner(), owner)) {
963 throw new InvalidLinkException(new SQLException());
964 }
965
966 if (!association.getTarget().isTheSameAs(target)
967 && !this.classFacade.isSuperClassTo(association.getTarget(), target)) {
968 throw new InvalidLinkException(new SQLException());
969 }
970 }
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986 private void checkAssociationMap(final MapAssociation association,
987 final Type owner,
988 final Type target,
989 final Type key) throws PersistenceException {
990 if (!association.getOwner().isTheSameAs(owner)
991 && !this.classFacade.isSuperClassTo(association.getOwner(), owner)
992 && !this.classFacade.isSuperClassTo(owner, association.getOwner())) {
993 throw new InvalidLinkException(null);
994 }
995
996 if (!association.getTarget().isTheSameAs(target)
997 && !this.classFacade.isSuperClassTo(association.getTarget(), target)
998 && !this.classFacade.isSuperClassTo(target, association.getTarget())) {
999 throw new InvalidLinkException(new SQLException());
1000 }
1001
1002 if (!association.getKeyType().isTheSameAs(key)
1003 && !this.classFacade.isSuperClassTo(association.getKeyType(), key)
1004 && !this.classFacade.isSuperClassTo(key, association.getKeyType())) {
1005 throw new InvalidLinkException(new SQLException());
1006 }
1007 }
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022 private void throwInvalidLinkExceptionIfWrongTypeForLink(final UserObject owner,
1023 final UnidirectionalAssociation association,
1024 final Object target) throws PersistenceException {
1025 if (!this.classFacade.isSuperClassTo(association.getTarget(), target.getInstanceOf())
1026 || !this.classFacade.isSuperClassTo(association.getOwner(), owner.getInstanceOf())) {
1027 throw new InvalidLinkException(new SQLException());
1028 }
1029 }
1030
1031 }