Skip to content

Commit 4144d78

Browse files
committed
Moved Sealable* to json-io from java-util
1 parent a3f1665 commit 4144d78

16 files changed

+681
-30
lines changed

src/main/java/com/cedarsoftware/io/factory/ImmutableListFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cedarsoftware.io.JsonObject;
44
import com.cedarsoftware.io.JsonReader;
55
import com.cedarsoftware.io.Resolver;
6-
import com.cedarsoftware.util.SealableList;
6+
import com.cedarsoftware.io.util.SealableList;
77

88
/**
99
* @author John DeRegnaucourt ([email protected])

src/main/java/com/cedarsoftware/io/factory/ImmutableSetFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cedarsoftware.io.JsonObject;
44
import com.cedarsoftware.io.JsonReader;
55
import com.cedarsoftware.io.Resolver;
6-
import com.cedarsoftware.util.SealableSet;
6+
import com.cedarsoftware.io.util.SealableSet;
77

88
/**
99
* @author John DeRegnaucourt ([email protected])

src/main/java/com/cedarsoftware/io/factory/SealableListFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cedarsoftware.io.JsonObject;
44
import com.cedarsoftware.io.JsonReader;
55
import com.cedarsoftware.io.Resolver;
6-
import com.cedarsoftware.util.SealableList;
6+
import com.cedarsoftware.io.util.SealableList;
77

88
/**
99
* @author John DeRegnaucourt ([email protected])

src/main/java/com/cedarsoftware/io/factory/SealableMapFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cedarsoftware.io.JsonObject;
44
import com.cedarsoftware.io.JsonReader;
55
import com.cedarsoftware.io.Resolver;
6-
import com.cedarsoftware.util.SealableMap;
6+
import com.cedarsoftware.io.util.SealableMap;
77

88
/**
99
* @author John DeRegnaucourt ([email protected])

src/main/java/com/cedarsoftware/io/factory/SealableNavigableMapFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cedarsoftware.io.JsonObject;
44
import com.cedarsoftware.io.JsonReader;
55
import com.cedarsoftware.io.Resolver;
6-
import com.cedarsoftware.util.SealableNavigableMap;
6+
import com.cedarsoftware.io.util.SealableNavigableMap;
77

88
/**
99
* @author John DeRegnaucourt ([email protected])

src/main/java/com/cedarsoftware/io/factory/SealableNavigableSetFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cedarsoftware.io.JsonObject;
44
import com.cedarsoftware.io.JsonReader;
55
import com.cedarsoftware.io.Resolver;
6-
import com.cedarsoftware.util.SealableNavigableSet;
6+
import com.cedarsoftware.io.util.SealableNavigableSet;
77

88
/**
99
* @author John DeRegnaucourt ([email protected])

src/main/java/com/cedarsoftware/io/factory/SealableSetFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.cedarsoftware.io.JsonObject;
44
import com.cedarsoftware.io.JsonReader;
55
import com.cedarsoftware.io.Resolver;
6-
import com.cedarsoftware.util.SealableSet;
6+
import com.cedarsoftware.io.util.SealableSet;
77

88
/**
99
* @author John DeRegnaucourt ([email protected])

src/main/java/com/cedarsoftware/io/factory/ThrowableFactory.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,4 @@ public Object newInstance(Class<?> c, JsonObject jObj, Resolver resolver)
7474
}
7575
return t;
7676
}
77-
78-
public boolean isObjectFinal()
79-
{
80-
return false;
81-
}
8277
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.cedarsoftware.io.util;
2+
3+
import java.util.Collection;
4+
import java.util.HashSet;
5+
import java.util.Iterator;
6+
import java.util.List;
7+
import java.util.ListIterator;
8+
import java.util.function.Supplier;
9+
10+
import com.cedarsoftware.util.ConcurrentList;
11+
12+
/**
13+
* SealableList provides a List or List wrapper that can be 'sealed' and 'unsealed.' When
14+
* sealed, the List is immutable, when unsealed it is mutable. The iterator(),
15+
* listIterator(), and subList() return views that honor the Supplier's sealed state.
16+
* The sealed state can be changed as often as needed.
17+
* <br><br>
18+
* NOTE: Please do not reformat this code as the current format makes it easy to see the overall structure.
19+
* <br><br>
20+
* @author John DeRegnaucourt ([email protected])
21+
* <br>
22+
* Copyright (c) Cedar Software LLC
23+
* <br><br>
24+
* Licensed under the Apache License, Version 2.0 (the "License");
25+
* you may not use this file except in compliance with the License.
26+
* You may obtain a copy of the License at
27+
* <br><br>
28+
* <a href="http://www.apache.org/licenses/LICENSE-2.0">License</a>
29+
* <br><br>
30+
* Unless required by applicable law or agreed to in writing, software
31+
* distributed under the License is distributed on an "AS IS" BASIS,
32+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33+
* See the License for the specific language governing permissions and
34+
* limitations under the License.
35+
*/
36+
public class SealableList<T> implements List<T> {
37+
private final List<T> list;
38+
private final transient Supplier<Boolean> sealedSupplier;
39+
40+
/**
41+
* Create a SealableList. Since no List is being supplied, this will use an ConcurrentList internally. If you
42+
* want to use an ArrayList for example, use SealableList constructor that takes a List and pass it the instance
43+
* you want it to wrap.
44+
* @param sealedSupplier {@code Supplier<Boolean>} that returns 'true' to indicate sealed, 'false' for mutable.
45+
*/
46+
public SealableList(Supplier<Boolean> sealedSupplier) {
47+
this.list = new ConcurrentList<>();
48+
this.sealedSupplier = sealedSupplier;
49+
}
50+
51+
/**
52+
* Create a SealableList. Since a List is not supplied, the elements from the passed in Collection will be
53+
* copied to an internal ConcurrentList. If you want to use an ArrayList for example, use SealableList
54+
* constructor that takes a List and pass it the instance you want it to wrap.
55+
* @param col Collection to supply initial elements. These are copied to an internal ConcurrentList.
56+
* @param sealedSupplier {@code Supplier<Boolean>} that returns 'true' to indicate sealed, 'false' for mutable.
57+
*/
58+
public SealableList(Collection<T> col, Supplier<Boolean> sealedSupplier) {
59+
this.list = new ConcurrentList<>();
60+
this.list.addAll(col);
61+
this.sealedSupplier = sealedSupplier;
62+
}
63+
64+
/**
65+
* Use this constructor to wrap a List (any kind of List) and make it a SealableList.
66+
* No duplicate of the List is created and the original list is operated on directly if unsealed, or protected
67+
* from changes if sealed.
68+
* @param list List instance to protect.
69+
* @param sealedSupplier {@code Supplier<Boolean>} that returns 'true' to indicate sealed, 'false' for mutable.
70+
*/
71+
public SealableList(List<T> list, Supplier<Boolean> sealedSupplier) {
72+
this.list = list;
73+
this.sealedSupplier = sealedSupplier;
74+
}
75+
76+
private void throwIfSealed() {
77+
if (sealedSupplier.get()) {
78+
throw new UnsupportedOperationException("This list has been sealed and is now immutable");
79+
}
80+
}
81+
82+
// Immutable APIs
83+
public boolean equals(Object other) { return list.equals(other); }
84+
public int hashCode() { return list.hashCode(); }
85+
public String toString() { return list.toString(); }
86+
public int size() { return list.size(); }
87+
public boolean isEmpty() { return list.isEmpty(); }
88+
public boolean contains(Object o) { return list.contains(o); }
89+
public boolean containsAll(Collection<?> col) { return new HashSet<>(list).containsAll(col); }
90+
public int indexOf(Object o) { return list.indexOf(o); }
91+
public int lastIndexOf(Object o) { return list.lastIndexOf(o); }
92+
public T get(int index) { return list.get(index); }
93+
public Object[] toArray() { return list.toArray(); }
94+
public <T1> T1[] toArray(T1[] a) { return list.toArray(a);}
95+
public Iterator<T> iterator() { return createSealHonoringIterator(list.iterator()); }
96+
public ListIterator<T> listIterator() { return createSealHonoringListIterator(list.listIterator()); }
97+
public ListIterator<T> listIterator(final int index) { return createSealHonoringListIterator(list.listIterator(index)); }
98+
public List<T> subList(int fromIndex, int toIndex) { return new SealableList<>(list.subList(fromIndex, toIndex), sealedSupplier); }
99+
100+
// Mutable APIs
101+
public boolean add(T t) { throwIfSealed(); return list.add(t); }
102+
public boolean remove(Object o) { throwIfSealed(); return list.remove(o); }
103+
public boolean addAll(Collection<? extends T> col) { throwIfSealed(); return list.addAll(col); }
104+
public boolean addAll(int index, Collection<? extends T> col) { throwIfSealed(); return list.addAll(index, col); }
105+
public boolean removeAll(Collection<?> col) { throwIfSealed(); return list.removeAll(col); }
106+
public boolean retainAll(Collection<?> col) { throwIfSealed(); return list.retainAll(col); }
107+
public void clear() { throwIfSealed(); list.clear(); }
108+
public T set(int index, T element) { throwIfSealed(); return list.set(index, element); }
109+
public void add(int index, T element) { throwIfSealed(); list.add(index, element); }
110+
public T remove(int index) { throwIfSealed(); return list.remove(index); }
111+
112+
private Iterator<T> createSealHonoringIterator(Iterator<T> iterator) {
113+
return new Iterator<T>() {
114+
public boolean hasNext() { return iterator.hasNext(); }
115+
public T next() { return iterator.next(); }
116+
public void remove() { throwIfSealed(); iterator.remove(); }
117+
};
118+
}
119+
120+
private ListIterator<T> createSealHonoringListIterator(ListIterator<T> iterator) {
121+
return new ListIterator<T>() {
122+
public boolean hasNext() { return iterator.hasNext();}
123+
public T next() { return iterator.next(); }
124+
public boolean hasPrevious() { return iterator.hasPrevious(); }
125+
public T previous() { return iterator.previous(); }
126+
public int nextIndex() { return iterator.nextIndex(); }
127+
public int previousIndex() { return iterator.previousIndex(); }
128+
public void remove() { throwIfSealed(); iterator.remove(); }
129+
public void set(T e) { throwIfSealed(); iterator.set(e); }
130+
public void add(T e) { throwIfSealed(); iterator.add(e);}
131+
};
132+
}
133+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.cedarsoftware.io.util;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Map;
6+
import java.util.Set;
7+
import java.util.function.Supplier;
8+
9+
import com.cedarsoftware.util.ConcurrentHashMapNullSafe;
10+
11+
/**
12+
* SealableMap provides a Map or Map wrapper that can be 'sealed' and 'unsealed.' When sealed, the
13+
* Map is mutable, when unsealed it is immutable (read-only). The view methods iterator(), keySet(),
14+
* values(), and entrySet() return a view that honors the Supplier's sealed state. The sealed state
15+
* can be changed as often as needed.
16+
* <br><br>
17+
* NOTE: Please do not reformat this code as the current format makes it easy to see the overall structure.
18+
* <br><br>
19+
* @author John DeRegnaucourt ([email protected])
20+
* <br>
21+
* Copyright (c) Cedar Software LLC
22+
* <br><br>
23+
* Licensed under the Apache License, Version 2.0 (the "License");
24+
* you may not use this file except in compliance with the License.
25+
* You may obtain a copy of the License at
26+
* <br><br>
27+
* <a href="http://www.apache.org/licenses/LICENSE-2.0">License</a>
28+
* <br><br>
29+
* Unless required by applicable law or agreed to in writing, software
30+
* distributed under the License is distributed on an "AS IS" BASIS,
31+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32+
* See the License for the specific language governing permissions and
33+
* limitations under the License.
34+
*/
35+
public class SealableMap<K, V> implements Map<K, V> {
36+
private final Map<K, V> map;
37+
private final transient Supplier<Boolean> sealedSupplier;
38+
39+
/**
40+
* Create a SealableMap. Since a Map is not supplied, this will use a ConcurrentHashMapNullSafe internally. If you
41+
* want a HashMap to be used internally, use the SealableMap constructor that takes a Map and pass it the
42+
* instance you want it to wrap.
43+
* @param sealedSupplier {@code Supplier<Boolean>} that returns 'true' to indicate sealed, 'false' for mutable.
44+
*/
45+
public SealableMap(Supplier<Boolean> sealedSupplier) {
46+
this.sealedSupplier = sealedSupplier;
47+
this.map = new ConcurrentHashMapNullSafe<>();
48+
}
49+
50+
/**
51+
* Use this constructor to wrap a Map (any kind of Map) and make it a SealableMap. No duplicate of the Map is
52+
* created and the original map is operated on directly if unsealed, or protected from changes if sealed.
53+
* @param map Map instance to protect.
54+
* @param sealedSupplier {@code Supplier<Boolean>} that returns 'true' to indicate sealed, 'false' for mutable.
55+
*/
56+
public SealableMap(Map<K, V> map, Supplier<Boolean> sealedSupplier) {
57+
this.sealedSupplier = sealedSupplier;
58+
this.map = map;
59+
}
60+
61+
private void throwIfSealed() {
62+
if (sealedSupplier.get()) {
63+
throw new UnsupportedOperationException("This map has been sealed and is now immutable");
64+
}
65+
}
66+
67+
// Immutable
68+
public boolean equals(Object obj) { return map.equals(obj); }
69+
public int hashCode() { return map.hashCode(); }
70+
public String toString() { return map.toString(); }
71+
public int size() { return map.size(); }
72+
public boolean isEmpty() { return map.isEmpty(); }
73+
public boolean containsKey(Object key) { return map.containsKey(key); }
74+
public boolean containsValue(Object value) { return map.containsValue(value); }
75+
public V get(Object key) { return map.get(key); }
76+
public Set<K> keySet() { return new SealableSet<>(map.keySet(), sealedSupplier); }
77+
public Collection<V> values() { return new SealableList<>(new ArrayList<>(map.values()), sealedSupplier); }
78+
public Set<Map.Entry<K, V>> entrySet() { return new SealableSet<>(map.entrySet(), sealedSupplier); }
79+
80+
// Mutable
81+
public V put(K key, V value) { throwIfSealed(); return map.put(key, value); }
82+
public V remove(Object key) { throwIfSealed(); return map.remove(key); }
83+
public void putAll(Map<? extends K, ? extends V> m) { throwIfSealed(); map.putAll(m); }
84+
public void clear() { throwIfSealed(); map.clear(); }
85+
}

0 commit comments

Comments
 (0)