summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/funcdata/TransformedValueMap.java
blob: 1e0ef51db4c5c02f488b3f114a8da5d5e9551794 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package bjc.funcdata;

import java.util.*;
import java.util.function.*;

/**
 * A map that transforms values from one type to another
 *
 * @author ben
 *
 * @param <OldKey>
 *                   The type of the map's keys
 *
 * @param <OldValue>
 *                   The type of the map's values
 *
 * @param <NewValue>
 *                   The type of the transformed values
 *
 */
final class TransformedValueMap<OldKey, OldValue, NewValue>
		implements IMap<OldKey, NewValue> {
	/* Our backing map. */
	private final IMap<OldKey, OldValue> backing;
	/* Our transforming function. */
	private final Function<OldValue, NewValue> transformer;

	private boolean isFrozen    = false;
	private boolean thawEnabled = true;
	
	/**
	 * Create a new transformed-value loop.
	 *
	 * @param backingMap
	 *                   The map to use as backing.
	 *
	 * @param transform
	 *                   The function to use for the transform.
	 */
	public TransformedValueMap(final IMap<OldKey, OldValue> backingMap,
			final Function<OldValue, NewValue> transform) {
		backing = backingMap;
		transformer = transform;
	}

	@Override
	public void clear() {
		if (isFrozen) throw new ObjectFrozen("Can't clear frozen map");
		
		backing.clear();
	}

	@Override
	public boolean containsKey(final OldKey key) {
		return backing.containsKey(key);
	}

	@Override
	public void forEach(final BiConsumer<OldKey, NewValue> action) {
		backing.forEach((key, value) -> {
			action.accept(key, transformer.apply(value));
		});
	}

	@Override
	public Optional<NewValue> get(final OldKey key) {
		return backing.get(key).map(transformer);
	}

	@Override
	public int size() {
		return backing.size();
	}

	@Override
	public IList<OldKey> keyList() {
		return backing.keyList();
	}

	@Override
	public NewValue put(final OldKey key, final NewValue value) {
		throw new UnsupportedOperationException("Can't add items to transformed map");
	}

	@Override
	public NewValue remove(final OldKey key) {
		if (isFrozen) throw new ObjectFrozen("Can't remove key " + key + " from frozen map");
		
		return transformer.apply(backing.remove(key));
	}

	@Override
	public String toString() {
		return backing.toString();
	}
	
	@Override
	public boolean freeze() {
		isFrozen = true;
		
		return true;
	}

	@Override
	public boolean thaw() {
		if (thawEnabled) {
			isFrozen = false;
			return true;
		} else {
			return false;
		}
	}

	@Override
	public boolean deepFreeze() {
		thawEnabled = false;
		
		return freeze();
	}
	
	@Override
	public boolean canFreeze() {
		return true;
	}
	
	@Override
	public boolean canThaw() {
		return thawEnabled;
	}
	
	@Override
	public boolean isFrozen() {
		return isFrozen;
	}
}