1 package de.japrost.jabudget.repository.inmemory;
2
3 import java.util.*;
4 import java.util.stream.Collectors;
5
6 import de.japrost.jabudget.domain.DomainException;
7 import de.japrost.jabudget.domain.DomainFailure;
8 import de.japrost.jabudget.domain.account.Account;
9 import de.japrost.jabudget.domain.account.Entry;
10 import de.japrost.jabudget.domain.account.EntryBuilder;
11 import de.japrost.jabudget.repository.AccountRepository;
12
13
14
15
16
17 public class InMemoryAccountRepository implements AccountRepository {
18
19 private final Map<String, Account> storage = new HashMap<>();
20 private final Map<String, Collection<Entry>> entryStorage = new HashMap<>();
21
22
23
24
25
26
27 @Override
28 public Account create(final Account account) throws DomainException {
29 if (storage.containsKey(account.getId())) {
30 throw new DomainException(DomainFailure.DUPLICATE_ENTITY);
31 }
32 return putInStoreDefensively(account);
33 }
34
35
36
37
38
39
40 @Override
41 public Account update(final Account account) throws DomainException {
42 if (!storage.containsKey(account.getId())) {
43 throw new DomainException(DomainFailure.MISSING_ENTITY);
44 }
45 return putInStoreDefensively(account);
46
47 }
48
49
50
51
52
53
54 @Override
55 public void replaceAll(final Set<Account> accounts) {
56 storage.clear();
57 entryStorage.clear();
58 accounts.forEach(this::putInStoreDefensively);
59 }
60
61 private Account putInStoreDefensively(final Account account) {
62 final Account accountToStore = new Account.Builder(account).build();
63 storage.put(account.getId(), accountToStore);
64 if (!entryStorage.containsKey(account.getId())) {
65 entryStorage.put(account.getId(), new ArrayList<Entry>());
66 }
67 return new Account.Builder(account).build();
68 }
69
70
71
72
73
74
75 @Override
76 public Optional<Account> findById(final String id) {
77 return Account.Builder.builder(storage.get(id)).buildOptional();
78 }
79
80
81
82
83
84
85 @Override
86 public Set<Account> findAll() {
87 return storage.values().stream().map(account -> new Account.Builder(account).build()).collect(Collectors.toSet());
88 }
89
90
91
92
93
94
95 @Override
96 public Boolean delete(final String accountId) {
97 storage.remove(accountId);
98 entryStorage.remove(accountId);
99 return Boolean.TRUE;
100 }
101
102 @Override
103 public Entry create(final Entry entry) throws DomainException {
104 Collection<Entry> entries = entryStorage.get(entry.getAccountId());
105 if (Objects.isNull(entries)) {
106 throw new DomainException(DomainFailure.MISSING_ENTITY_REFERENCE);
107 }
108 if (entries.contains(entry)) {
109 throw new DomainException(DomainFailure.DUPLICATE_ENTITY);
110 }
111 return putInStoreDefensively(entries, entry);
112 }
113
114 private Entry putInStoreDefensively(final Collection<Entry> entries, final Entry value) {
115 final Entry toStore = EntryBuilder.builder(value).build();
116 entries.add(toStore);
117 return EntryBuilder.builder(toStore).build();
118 }
119
120 }