Skip to content

Commit 4e5998f

Browse files
committed
Refactor UnmodifiableListDeserializer and UnmodifiableSetDeserializer to Use Abstract Base Class
1 parent 596ab18 commit 4e5998f

File tree

3 files changed

+92
-45
lines changed

3 files changed

+92
-45
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.jackson2;
18+
19+
import com.fasterxml.jackson.core.JsonParser;
20+
import com.fasterxml.jackson.databind.DeserializationContext;
21+
import com.fasterxml.jackson.databind.JsonDeserializer;
22+
import com.fasterxml.jackson.databind.JsonNode;
23+
import com.fasterxml.jackson.databind.ObjectMapper;
24+
import com.fasterxml.jackson.databind.node.ArrayNode;
25+
26+
import java.io.IOException;
27+
import java.util.Collection;
28+
import java.util.List;
29+
import java.util.Set;
30+
31+
/**
32+
* Abstract base class for deserializers that create unmodifiable collections from JSON data.
33+
* Subclasses like {@link UnmodifiableListDeserializer} and
34+
* {@link UnmodifiableSetDeserializer} should implement the method to define the
35+
* specific collection type and handle the deserialization logic.
36+
*
37+
* @param <T> the type of the unmodifiable collection, such as {@link List} or {@link Set}.
38+
* @author Hyunmin Choi
39+
*/
40+
abstract class AbstractUnmodifiableCollectionDeserializer<T> extends JsonDeserializer<T> {
41+
42+
@Override
43+
public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
44+
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
45+
JsonNode node = mapper.readTree(jp);
46+
return createUnmodifiableCollection(node, mapper);
47+
}
48+
49+
/**
50+
* Creates an unmodifiable collection from the given JSON node.
51+
*
52+
* @param node the JSON node containing the data to be deserialized.
53+
* @param mapper the {@link ObjectMapper} used to deserialize JSON data.
54+
* @return an unmodifiable collection with the deserialized elements.
55+
* @throws IOException if an error occurs during deserialization.
56+
*/
57+
protected abstract T createUnmodifiableCollection(JsonNode node, ObjectMapper mapper) throws IOException;
58+
59+
/**
60+
* Adds elements from the JSON node to the provided collection.
61+
*
62+
* @param node the JSON node containing the elements to add.
63+
* @param mapper the {@link ObjectMapper} used for deserialization.
64+
* @param collection the collection to which elements are added.
65+
* @throws IOException if an error occurs during deserialization.
66+
*/
67+
protected void addElements(JsonNode node, ObjectMapper mapper, Collection<Object> collection) throws IOException {
68+
if (node instanceof ArrayNode arrayNode) {
69+
for (JsonNode elementNode : arrayNode) {
70+
collection.add(mapper.readValue(elementNode.traverse(mapper), Object.class));
71+
}
72+
} else if (node != null) {
73+
collection.add(mapper.readValue(node.traverse(mapper), Object.class));
74+
}
75+
}
76+
77+
}

core/src/main/java/org/springframework/security/jackson2/UnmodifiableListDeserializer.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,28 @@
1616

1717
package org.springframework.security.jackson2;
1818

19+
import com.fasterxml.jackson.databind.JsonNode;
20+
import com.fasterxml.jackson.databind.ObjectMapper;
21+
1922
import java.io.IOException;
2023
import java.util.ArrayList;
2124
import java.util.Collections;
2225
import java.util.List;
2326

24-
import com.fasterxml.jackson.core.JsonParser;
25-
import com.fasterxml.jackson.core.JsonProcessingException;
26-
import com.fasterxml.jackson.databind.DeserializationContext;
27-
import com.fasterxml.jackson.databind.JsonDeserializer;
28-
import com.fasterxml.jackson.databind.JsonNode;
29-
import com.fasterxml.jackson.databind.ObjectMapper;
30-
import com.fasterxml.jackson.databind.node.ArrayNode;
31-
3227
/**
33-
* Custom deserializer for {@link UnmodifiableListDeserializer}.
28+
* Custom deserializer for {@link UnmodifiableListMixin}.
3429
*
3530
* @author Rob Winch
31+
* @author Hyunmin Choi
3632
* @since 5.0.2
3733
* @see UnmodifiableListMixin
3834
*/
39-
class UnmodifiableListDeserializer extends JsonDeserializer<List> {
35+
class UnmodifiableListDeserializer extends AbstractUnmodifiableCollectionDeserializer<List> {
4036

4137
@Override
42-
public List deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
43-
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
44-
JsonNode node = mapper.readTree(jp);
38+
protected List createUnmodifiableCollection(JsonNode node, ObjectMapper mapper) throws IOException {
4539
List<Object> result = new ArrayList<>();
46-
if (node != null) {
47-
if (node instanceof ArrayNode arrayNode) {
48-
for (JsonNode elementNode : arrayNode) {
49-
result.add(mapper.readValue(elementNode.traverse(mapper), Object.class));
50-
}
51-
}
52-
else {
53-
result.add(mapper.readValue(node.traverse(mapper), Object.class));
54-
}
55-
}
40+
addElements(node, mapper, result);
5641
return Collections.unmodifiableList(result);
5742
}
5843

core/src/main/java/org/springframework/security/jackson2/UnmodifiableSetDeserializer.java

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,28 @@
1616

1717
package org.springframework.security.jackson2;
1818

19+
import com.fasterxml.jackson.databind.JsonNode;
20+
import com.fasterxml.jackson.databind.ObjectMapper;
21+
1922
import java.io.IOException;
2023
import java.util.Collections;
2124
import java.util.HashSet;
2225
import java.util.Set;
2326

24-
import com.fasterxml.jackson.core.JsonParser;
25-
import com.fasterxml.jackson.core.JsonProcessingException;
26-
import com.fasterxml.jackson.databind.DeserializationContext;
27-
import com.fasterxml.jackson.databind.JsonDeserializer;
28-
import com.fasterxml.jackson.databind.JsonNode;
29-
import com.fasterxml.jackson.databind.ObjectMapper;
30-
import com.fasterxml.jackson.databind.node.ArrayNode;
31-
3227
/**
3328
* Custom deserializer for {@link UnmodifiableSetMixin}.
3429
*
3530
* @author Jitendra Singh
31+
* @author Hyunmin Choi
3632
* @since 4.2
3733
* @see UnmodifiableSetMixin
3834
*/
39-
class UnmodifiableSetDeserializer extends JsonDeserializer<Set> {
35+
class UnmodifiableSetDeserializer extends AbstractUnmodifiableCollectionDeserializer<Set> {
4036

4137
@Override
42-
public Set deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
43-
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
44-
JsonNode node = mapper.readTree(jp);
38+
protected Set createUnmodifiableCollection(JsonNode node, ObjectMapper mapper) throws IOException {
4539
Set<Object> resultSet = new HashSet<>();
46-
if (node != null) {
47-
if (node instanceof ArrayNode arrayNode) {
48-
for (JsonNode elementNode : arrayNode) {
49-
resultSet.add(mapper.readValue(elementNode.traverse(mapper), Object.class));
50-
}
51-
}
52-
else {
53-
resultSet.add(mapper.readValue(node.traverse(mapper), Object.class));
54-
}
55-
}
40+
addElements(node, mapper, resultSet);
5641
return Collections.unmodifiableSet(resultSet);
5742
}
5843

0 commit comments

Comments
 (0)