Skip to content

Commit d4bc385

Browse files
committed
- Support Synchronized collections more accurately.
- Support Checked collections getting loaded.
1 parent 066ab6e commit d4bc385

File tree

9 files changed

+350
-39
lines changed

9 files changed

+350
-39
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.cedarsoftware.io.factory;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.LinkedHashMap;
6+
import java.util.LinkedHashSet;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.NavigableMap;
10+
import java.util.NavigableSet;
11+
import java.util.Set;
12+
import java.util.SortedMap;
13+
import java.util.SortedSet;
14+
import java.util.TreeMap;
15+
import java.util.TreeSet;
16+
17+
import com.cedarsoftware.io.JsonIoException;
18+
import com.cedarsoftware.io.JsonObject;
19+
import com.cedarsoftware.io.JsonReader;
20+
import com.cedarsoftware.io.Resolver;
21+
22+
/**
23+
* @author John DeRegnaucourt ([email protected])
24+
* <br>
25+
* Copyright (c) Cedar Software LLC
26+
* <br><br>
27+
* Licensed under the Apache License, Version 2.0 (the "License");
28+
* you may not use this file except in compliance with the License.
29+
* You may obtain a copy of the License at
30+
* <br><br>
31+
* <a href="http://www.apache.org/licenses/LICENSE-2.0">License</a>
32+
* <br><br>
33+
* Unless required by applicable law or agreed to in writing, software
34+
* distributed under the License is distributed on an "AS IS" BASIS,
35+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36+
* See the License for the specific language governing permissions and
37+
* limitations under the License.
38+
*/
39+
public class CheckedFactory implements JsonReader.ClassFactory {
40+
public Object newInstance(Class<?> c, JsonObject jObj, Resolver resolver) {
41+
if (NavigableSet.class.isAssignableFrom(c)) {
42+
return new TreeSet<>();
43+
} else if (SortedSet.class.isAssignableFrom(c)) {
44+
return new TreeSet<>();
45+
} else if (Set.class.isAssignableFrom(c)) {
46+
return new LinkedHashSet<>();
47+
} else if (List.class.isAssignableFrom(c)) {
48+
return new ArrayList<>();
49+
} else if (Collection.class.isAssignableFrom(c)) {
50+
return new ArrayList<>();
51+
} else if (NavigableMap.class.isAssignableFrom(c)) {
52+
return new TreeMap<>();
53+
} else if (SortedMap.class.isAssignableFrom(c)) {
54+
return new TreeMap<>();
55+
} else if (Map.class.isAssignableFrom(c)) {
56+
return new LinkedHashMap<>();
57+
}
58+
throw new JsonIoException("CheckedFactory handed Class for which it was not expecting: " + c.getName());
59+
}
60+
}
61+

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,18 @@
3737
*/
3838
public class EmptyFactory implements JsonReader.ClassFactory {
3939
public Object newInstance(Class<?> c, JsonObject jObj, Resolver resolver) {
40-
if (NavigableSet.class.isAssignableFrom(c) || SortedSet.class.isAssignableFrom(c)) {
40+
if (NavigableSet.class.isAssignableFrom(c)) {
4141
return Collections.emptyNavigableSet();
42+
} else if (SortedSet.class.isAssignableFrom(c)) {
43+
return Collections.emptySortedSet();
4244
} else if (Set.class.isAssignableFrom(c)) {
4345
return Collections.emptySet();
4446
} else if (List.class.isAssignableFrom(c) || Collection.class.isAssignableFrom(c)) {
4547
return Collections.emptyList();
46-
} else if (NavigableMap.class.isAssignableFrom(c) || SortedMap.class.isAssignableFrom(c)) {
48+
} else if (NavigableMap.class.isAssignableFrom(c)) {
4749
return Collections.emptyNavigableMap();
50+
} else if (SortedMap.class.isAssignableFrom(c)) {
51+
return Collections.emptySortedMap();
4852
} else if (Map.class.isAssignableFrom(c)) {
4953
return Collections.emptyMap();
5054
} else if (ListIterator.class.isAssignableFrom(c)) {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.cedarsoftware.io.factory;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Collections;
6+
import java.util.LinkedHashMap;
7+
import java.util.LinkedHashSet;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.NavigableMap;
11+
import java.util.NavigableSet;
12+
import java.util.Set;
13+
import java.util.SortedMap;
14+
import java.util.SortedSet;
15+
import java.util.TreeMap;
16+
import java.util.TreeSet;
17+
18+
import com.cedarsoftware.io.JsonIoException;
19+
import com.cedarsoftware.io.JsonObject;
20+
import com.cedarsoftware.io.JsonReader;
21+
import com.cedarsoftware.io.Resolver;
22+
23+
/**
24+
* @author John DeRegnaucourt ([email protected])
25+
* <br>
26+
* Copyright (c) Cedar Software LLC
27+
* <br><br>
28+
* Licensed under the Apache License, Version 2.0 (the "License");
29+
* you may not use this file except in compliance with the License.
30+
* You may obtain a copy of the License at
31+
* <br><br>
32+
* <a href="http://www.apache.org/licenses/LICENSE-2.0">License</a>
33+
* <br><br>
34+
* Unless required by applicable law or agreed to in writing, software
35+
* distributed under the License is distributed on an "AS IS" BASIS,
36+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37+
* See the License for the specific language governing permissions and
38+
* limitations under the License.
39+
*/
40+
public class SynchronizedFactory implements JsonReader.ClassFactory {
41+
public Object newInstance(Class<?> c, JsonObject jObj, Resolver resolver) {
42+
if (NavigableSet.class.isAssignableFrom(c)) {
43+
return Collections.synchronizedNavigableSet(new TreeSet<>());
44+
} else if (SortedSet.class.isAssignableFrom(c)) {
45+
return Collections.synchronizedSortedSet(new TreeSet<>());
46+
} else if (Set.class.isAssignableFrom(c)) {
47+
return Collections.synchronizedSet(new LinkedHashSet<>());
48+
} else if (List.class.isAssignableFrom(c)) {
49+
return Collections.synchronizedList(new ArrayList<>());
50+
} else if (Collection.class.isAssignableFrom(c)) {
51+
return Collections.synchronizedCollection(new ArrayList<>());
52+
} else if (NavigableMap.class.isAssignableFrom(c)) {
53+
return Collections.synchronizedNavigableMap(new TreeMap<>());
54+
} else if (SortedMap.class.isAssignableFrom(c)) {
55+
return Collections.synchronizedSortedMap(new TreeMap<>());
56+
} else if (Map.class.isAssignableFrom(c)) {
57+
return Collections.synchronizedMap(new LinkedHashMap<>());
58+
}
59+
throw new JsonIoException("SynchronizedFactory handed Class for which it was not expecting: " + c.getName());
60+
}
61+
}
62+

src/main/java/com/cedarsoftware/io/factory/SealableFactory.java renamed to src/main/java/com/cedarsoftware/io/factory/UnmodifiableFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* See the License for the specific language governing permissions and
3838
* limitations under the License.
3939
*/
40-
public class SealableFactory implements JsonReader.ClassFactory {
40+
public class UnmodifiableFactory implements JsonReader.ClassFactory {
4141
public Object newInstance(Class<?> c, JsonObject jObj, Resolver resolver) {
4242
SealedSupplier supplier = resolver.getSealedSupplier();
4343
if (NavigableSet.class.isAssignableFrom(c) || SortedSet.class.isAssignableFrom(c)) {

src/main/resources/config/aliases.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,17 @@ java.util.Collections$SynchronizedMap = SynchronizedMap
164164
java.util.Collections$SynchronizedSortedMap = SynchronizedSortedMap
165165
java.util.Collections$SynchronizedNavigableMap = SynchronizedNavigableMap
166166

167+
# Collections "checked" types
168+
java.util.Collections$CheckedCollection = CheckedCollection
169+
java.util.Collections$CheckedList = CheckedList
170+
java.util.Collections$CheckedRandomAccessList = CheckedRandomAccessList
171+
java.util.Collections$CheckedSet = CheckedSet
172+
java.util.Collections$CheckedSortedSet = CheckedSortedSet
173+
java.util.Collections$CheckedNavigableSet = CheckedNavigableSet
174+
java.util.Collections$CheckedMap = CheckedMap
175+
java.util.Collections$CheckedSortedMap = CheckedSortedMap
176+
java.util.Collections$CheckedNavigableMap = CheckedNavigableMap
177+
167178
# Collections "concurrent" types
168179
java.util.concurrent.ConcurrentHashMap = ConcurrentHashMap
169180
java.util.concurrent.ConcurrentSkipListMap = ConcurrentSkipListMap

src/main/resources/config/classFactory.txt

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,12 @@ sun.util.calendar.ZoneInfo = Convertable
137137
[Ljava.time.ZoneOffset; = ArrayFactory
138138
[Ljava.time.ZoneRegion; = ArrayFactory
139139

140-
# Use factory classes to re-create Singleton Collections classes as they are not easily instantiated
140+
# Use factory classes to re-create "singleton" Collections classes as they are not easily instantiated
141141
java.util.Collections$SingletonList = com.cedarsoftware.io.factory.SingletonFactory
142142
java.util.Collections$SingletonSet = com.cedarsoftware.io.factory.SingletonFactory
143143
java.util.Collections$SingletonMap = com.cedarsoftware.io.factory.SingletonFactory
144144

145-
# Use factory classes to re-create empty Collections classes as they are not easily instantiated
145+
# Use factory classes to re-create "empty" Collections classes as they are not easily instantiated
146146
java.util.Collections$EmptyEnumeration = com.cedarsoftware.io.factory.EmptyFactory
147147
java.util.Collections$EmptyIterator = com.cedarsoftware.io.factory.EmptyFactory
148148
java.util.Collections$EmptyListIterator = com.cedarsoftware.io.factory.EmptyFactory
@@ -152,26 +152,48 @@ java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet = com.cedarsoft
152152
java.util.Collections$EmptyMap = com.cedarsoftware.io.factory.EmptyFactory
153153
java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap = com.cedarsoftware.io.factory.EmptyFactory
154154

155-
# Use factory classes to re-create unmodifiable Collections classes
156-
java.util.Collections$UnmodifiableCollection = com.cedarsoftware.io.factory.SealableFactory
157-
java.util.Collections$UnmodifiableList = com.cedarsoftware.io.factory.SealableFactory
158-
java.util.Collections$UnmodifiableRandomAccessList = com.cedarsoftware.io.factory.SealableFactory
159-
java.util.Collections$UnmodifiableSet = com.cedarsoftware.io.factory.SealableFactory
160-
java.util.Collections$UnmodifiableSortedSet = com.cedarsoftware.io.factory.SealableFactory
161-
java.util.Collections$UnmodifiableNavigableSet = com.cedarsoftware.io.factory.SealableFactory
162-
java.util.Collections$UnmodifiableMap = com.cedarsoftware.io.factory.SealableFactory
163-
java.util.Collections$UnmodifiableSortedMap = com.cedarsoftware.io.factory.SealableFactory
164-
java.util.Collections$UnmodifiableNavigableMap = com.cedarsoftware.io.factory.SealableFactory
165-
166-
com.cedarsoftware.io.util.SealableList = com.cedarsoftware.io.factory.SealableFactory
167-
com.cedarsoftware.io.util.SealableSet = com.cedarsoftware.io.factory.SealableFactory
168-
com.cedarsoftware.io.util.SealableNavigableSet = com.cedarsoftware.io.factory.SealableFactory
169-
com.cedarsoftware.io.util.SealableMap = com.cedarsoftware.io.factory.SealableFactory
170-
com.cedarsoftware.io.util.SealableNavigableMap = com.cedarsoftware.io.factory.SealableFactory
171-
172-
java.util.ImmutableCollections$ListN = com.cedarsoftware.io.factory.SealableFactory
173-
java.util.ImmutableCollections$List12 = com.cedarsoftware.io.factory.SealableFactory
174-
java.util.ImmutableCollections$SetN = com.cedarsoftware.io.factory.SealableFactory
175-
java.util.ImmutableCollections$Set12 = com.cedarsoftware.io.factory.SealableFactory
155+
# Use factory classes to re-create "unmodifiable" Collections classes
156+
java.util.Collections$UnmodifiableCollection = com.cedarsoftware.io.factory.UnmodifiableFactory
157+
java.util.Collections$UnmodifiableList = com.cedarsoftware.io.factory.UnmodifiableFactory
158+
java.util.Collections$UnmodifiableRandomAccessList = com.cedarsoftware.io.factory.UnmodifiableFactory
159+
java.util.Collections$UnmodifiableSet = com.cedarsoftware.io.factory.UnmodifiableFactory
160+
java.util.Collections$UnmodifiableSortedSet = com.cedarsoftware.io.factory.UnmodifiableFactory
161+
java.util.Collections$UnmodifiableNavigableSet = com.cedarsoftware.io.factory.UnmodifiableFactory
162+
java.util.Collections$UnmodifiableMap = com.cedarsoftware.io.factory.UnmodifiableFactory
163+
java.util.Collections$UnmodifiableSortedMap = com.cedarsoftware.io.factory.UnmodifiableFactory
164+
java.util.Collections$UnmodifiableNavigableMap = com.cedarsoftware.io.factory.UnmodifiableFactory
165+
166+
# Use SynchronizedFactory to instantiate "synchronized" Collections classes
167+
java.util.Collections$SynchronizedCollection = com.cedarsoftware.io.factory.SynchronizedFactory
168+
java.util.Collections$SynchronizedList = com.cedarsoftware.io.factory.SynchronizedFactory
169+
java.util.Collections$SynchronizedRandomAccessList = com.cedarsoftware.io.factory.SynchronizedFactory
170+
java.util.Collections$SynchronizedSet = com.cedarsoftware.io.factory.SynchronizedFactory
171+
java.util.Collections$SynchronizedSortedSet = com.cedarsoftware.io.factory.SynchronizedFactory
172+
java.util.Collections$SynchronizedNavigableSet = com.cedarsoftware.io.factory.SynchronizedFactory
173+
java.util.Collections$SynchronizedMap = com.cedarsoftware.io.factory.SynchronizedFactory
174+
java.util.Collections$SynchronizedSortedMap = com.cedarsoftware.io.factory.SynchronizedFactory
175+
java.util.Collections$SynchronizedNavigableMap = com.cedarsoftware.io.factory.SynchronizedFactory
176+
177+
# Use CheckedFactory to instantiate "checked" Collections classes
178+
java.util.Collections$CheckedCollection = com.cedarsoftware.io.factory.CheckedFactory
179+
java.util.Collections$CheckedList = com.cedarsoftware.io.factory.CheckedFactory
180+
java.util.Collections$CheckedRandomAccessList = com.cedarsoftware.io.factory.CheckedFactory
181+
java.util.Collections$CheckedSet = com.cedarsoftware.io.factory.CheckedFactory
182+
java.util.Collections$CheckedSortedSet = com.cedarsoftware.io.factory.CheckedFactory
183+
java.util.Collections$CheckedNavigableSet = com.cedarsoftware.io.factory.CheckedFactory
184+
java.util.Collections$CheckedMap = com.cedarsoftware.io.factory.CheckedFactory
185+
java.util.Collections$CheckedSortedMap = com.cedarsoftware.io.factory.CheckedFactory
186+
java.util.Collections$CheckedNavigableMap = com.cedarsoftware.io.factory.CheckedFactory
187+
188+
com.cedarsoftware.io.util.SealableList = com.cedarsoftware.io.factory.UnmodifiableFactory
189+
com.cedarsoftware.io.util.SealableSet = com.cedarsoftware.io.factory.UnmodifiableFactory
190+
com.cedarsoftware.io.util.SealableNavigableSet = com.cedarsoftware.io.factory.UnmodifiableFactory
191+
com.cedarsoftware.io.util.SealableMap = com.cedarsoftware.io.factory.UnmodifiableFactory
192+
com.cedarsoftware.io.util.SealableNavigableMap = com.cedarsoftware.io.factory.UnmodifiableFactory
193+
194+
java.util.ImmutableCollections$ListN = com.cedarsoftware.io.factory.UnmodifiableFactory
195+
java.util.ImmutableCollections$List12 = com.cedarsoftware.io.factory.UnmodifiableFactory
196+
java.util.ImmutableCollections$SetN = com.cedarsoftware.io.factory.UnmodifiableFactory
197+
java.util.ImmutableCollections$Set12 = com.cedarsoftware.io.factory.UnmodifiableFactory
176198

177199
java.util.EnumSet = com.cedarsoftware.io.factory.EnumSetFactory

src/main/resources/config/coercedTypes.txt

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,9 @@ java.time.ZoneRegion = java.time.ZoneId
66

77
java.util.Arrays$ArrayList = java.util.ArrayList
88

9-
# Either coerce the following types or write a ClassFactory for them
10-
java.util.Collections$SynchronizedCollection = com.cedarsoftware.util.ConcurrentList
11-
java.util.Collections$SynchronizedList = com.cedarsoftware.util.ConcurrentList
12-
java.util.Collections$SynchronizedRandomAccessList = com.cedarsoftware.util.ConcurrentList
13-
java.util.Collections$SynchronizedSet = com.cedarsoftware.util.ConcurrentSet
14-
java.util.Collections$SynchronizedSortedSet = java.util.concurrent.ConcurrentSkipListSet
15-
java.util.Collections$SynchronizedNavigableSet = java.util.concurrent.ConcurrentSkipListSet
16-
java.util.Collections$SynchronizedMap = java.util.concurrent.ConcurrentHashMap
17-
java.util.Collections$SynchronizedSortedMap = java.util.concurrent.ConcurrentSkipListMap
18-
java.util.Collections$SynchronizedNavigableMap = java.util.concurrent.ConcurrentSkipListMap
19-
209
java.util.concurrent.ConcurrentHashMap$KeySetView = com.cedarsoftware.util.ConcurrentSet
2110
java.util.concurrent.ConcurrentHashMap$ValuesView = com.cedarsoftware.util.ConcurrentList
22-
java.util.concurrent.ConcurrentSkipListMap$KeySet = com.cedarsoftware.util.ConcurrentSet
11+
java.util.concurrent.ConcurrentSkipListMap$KeySet = com.cedarsoftware.util.ConcurrentNavigableSetNullSafe
2312
java.util.concurrent.ConcurrentSkipListMap$Values = com.cedarsoftware.util.ConcurrentList
2413

2514
java.util.HashMap$KeySet = java.util.HashSet

0 commit comments

Comments
 (0)