Skip to content

Commit 4c1a5fb

Browse files
committed
Hacking.
1 parent 3cbd98e commit 4c1a5fb

19 files changed

+764
-84
lines changed

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@
7070
<artifactId>jackson-databind</artifactId>
7171
<optional>true</optional>
7272
</dependency>
73+
<dependency>
74+
<groupId>tools.jackson.core</groupId>
75+
<artifactId>jackson-databind</artifactId>
76+
<optional>true</optional>
77+
</dependency>
7378
<dependency>
7479
<groupId>org.springframework</groupId>
7580
<artifactId>spring-web</artifactId>

src/main/java/org/springframework/data/geo/GeoModule.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,17 @@
1515
*/
1616
package org.springframework.data.geo;
1717

18+
import tools.jackson.core.Version;
19+
import tools.jackson.databind.annotation.JsonDeserialize;
20+
import tools.jackson.databind.module.SimpleModule;
21+
1822
import java.io.Serial;
1923
import java.util.List;
2024

2125
import com.fasterxml.jackson.annotation.JsonIgnore;
2226
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
2327
import com.fasterxml.jackson.annotation.JsonProperty;
24-
import com.fasterxml.jackson.core.Version;
25-
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
26-
import com.fasterxml.jackson.databind.module.SimpleModule;
28+
2729

2830
/**
2931
* Custom module to deserialize the geo-spatial value objects using Jackson 2.

src/main/java/org/springframework/data/repository/init/Jackson2RepositoryPopulatorFactoryBean.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
* @author Oliver Gierke
2828
* @author Christoph Strobl
2929
* @since 1.6
30+
* @deprecated since 4.0, in favor of {@link JacksonRepositoryPopulatorFactoryBean}.
3031
*/
32+
@Deprecated(since = "4.0", forRemoval = true)
3133
public class Jackson2RepositoryPopulatorFactoryBean extends AbstractRepositoryPopulatorFactoryBean {
3234

3335
private @Nullable ObjectMapper mapper;

src/main/java/org/springframework/data/repository/init/Jackson2ResourceReader.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
* @author Mark Paluch
4141
* @author Johannes Englmeier
4242
* @since 1.6
43+
* @deprecated since 4.0, in favor of {@link JacksonResourceReader}.
4344
*/
45+
@Deprecated(since = "4.0", forRemoval = true)
4446
public class Jackson2ResourceReader implements ResourceReader {
4547

4648
private static final String DEFAULT_TYPE_KEY = "_class";
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2025 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+
package org.springframework.data.repository.init;
17+
18+
import tools.jackson.databind.ObjectMapper;
19+
20+
import org.jspecify.annotations.Nullable;
21+
22+
import org.springframework.beans.factory.FactoryBean;
23+
24+
/**
25+
* {@link FactoryBean} to set up a {@link ResourceReaderRepositoryPopulator} with a {@link JacksonResourceReader}.
26+
*
27+
* @author Mark Paluch
28+
* @author Oliver Gierke
29+
* @author Christoph Strobl
30+
* @since 4.0
31+
*/
32+
public class JacksonRepositoryPopulatorFactoryBean extends AbstractRepositoryPopulatorFactoryBean {
33+
34+
private @Nullable ObjectMapper mapper;
35+
36+
/**
37+
* Configures the {@link ObjectMapper} to be used.
38+
*
39+
* @param mapper can be {@literal null}.
40+
*/
41+
public void setMapper(@Nullable ObjectMapper mapper) {
42+
this.mapper = mapper;
43+
}
44+
45+
@Override
46+
protected ResourceReader getResourceReader() {
47+
return mapper == null ? new JacksonResourceReader() : new JacksonResourceReader(mapper);
48+
}
49+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2013-2025 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+
package org.springframework.data.repository.init;
17+
18+
import tools.jackson.databind.DeserializationFeature;
19+
import tools.jackson.databind.JsonNode;
20+
import tools.jackson.databind.ObjectMapper;
21+
import tools.jackson.databind.json.JsonMapper;
22+
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
import java.util.ArrayList;
26+
import java.util.Iterator;
27+
import java.util.List;
28+
29+
import org.jspecify.annotations.Nullable;
30+
31+
import org.springframework.core.io.Resource;
32+
import org.springframework.util.Assert;
33+
import org.springframework.util.ClassUtils;
34+
35+
/**
36+
* A {@link ResourceReader} using Jackson to read JSON into objects.
37+
*
38+
* @author Oliver Gierke
39+
* @author Christoph Strobl
40+
* @author Mark Paluch
41+
* @author Johannes Englmeier
42+
* @since 4.0
43+
*/
44+
public class JacksonResourceReader implements ResourceReader {
45+
46+
private static final String DEFAULT_TYPE_KEY = "_class";
47+
private static final ObjectMapper DEFAULT_MAPPER = JsonMapper.builder()
48+
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build();
49+
50+
private final ObjectMapper mapper;
51+
private String typeKey = DEFAULT_TYPE_KEY;
52+
53+
/**
54+
* Creates a new {@link JacksonResourceReader}.
55+
*/
56+
public JacksonResourceReader() {
57+
this(DEFAULT_MAPPER);
58+
}
59+
60+
/**
61+
* Creates a new {@link JacksonResourceReader} using the given {@link ObjectMapper}.
62+
*
63+
* @param mapper
64+
*/
65+
public JacksonResourceReader(ObjectMapper mapper) {
66+
this.mapper = mapper;
67+
}
68+
69+
/**
70+
* Configures the JSON document's key to look up the type to instantiate the object. Defaults to
71+
* {@link JacksonResourceReader#DEFAULT_TYPE_KEY}.
72+
*
73+
* @param typeKey
74+
*/
75+
public void setTypeKey(@Nullable String typeKey) {
76+
this.typeKey = typeKey == null ? DEFAULT_TYPE_KEY : typeKey;
77+
}
78+
79+
@Override
80+
public Object readFrom(Resource resource, @Nullable ClassLoader classLoader) throws Exception {
81+
82+
Assert.notNull(resource, "Resource must not be null");
83+
84+
InputStream stream = resource.getInputStream();
85+
JsonNode node = mapper.readerFor(JsonNode.class).readTree(stream);
86+
87+
if (node.isArray()) {
88+
89+
Iterator<JsonNode> elements = node.iterator();
90+
List<Object> result = new ArrayList<>();
91+
92+
while (elements.hasNext()) {
93+
JsonNode element = elements.next();
94+
result.add(readSingle(element, classLoader));
95+
}
96+
97+
return result;
98+
}
99+
100+
return readSingle(node, classLoader);
101+
}
102+
103+
/**
104+
* Reads the given {@link JsonNode} into an instance of the type encoded in it using the configured type key.
105+
*
106+
* @param node must not be {@literal null}.
107+
* @param classLoader can be {@literal null}.
108+
* @return
109+
*/
110+
private Object readSingle(JsonNode node, @Nullable ClassLoader classLoader) throws IOException {
111+
112+
JsonNode typeNode = node.findValue(typeKey);
113+
114+
if (typeNode == null) {
115+
throw new IllegalArgumentException(String.format("Could not find type for type key '%s'", typeKey));
116+
}
117+
118+
String typeName = typeNode.asString();
119+
Class<?> type = ClassUtils.resolveClassName(typeName, classLoader);
120+
121+
return mapper.readerFor(type).readValue(node);
122+
}
123+
}

src/main/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@
4848
* @author Christoph Strobl
4949
* @soundtrack Richard Spaven - Ice Is Nice (Spaven's 5ive)
5050
* @since 1.13
51+
* @deprecated since 4.0, in favor of {@link ProjectingJacksonHttpMessageConverter}.
5152
*/
53+
@Deprecated(since = "4.0", forRemoval = true)
5254
public class ProjectingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter
5355
implements BeanClassLoaderAware, BeanFactoryAware {
5456

0 commit comments

Comments
 (0)