Skip to content

Commit 45861a6

Browse files
authored
Make sure the mappers are initialized once (#784)
1 parent 4ccf2dc commit 45861a6

2 files changed

Lines changed: 103 additions & 15 deletions

File tree

aom/src/main/java/com/nedap/archie/rminfo/MetaModel.java

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ public class MetaModel implements MetaModelInterface {
1919
private final ModelInfoLookup modelInfoLookup;
2020
private final BmmModel bmmModel;
2121
private final AomProfile aomProfile;
22-
private final ObjectMapper odinInputObjectMapper;
23-
private final ObjectMapper odinOutputObjectMapper;
24-
private final ObjectMapper jsonObjectMapper;
22+
private final RMObjectMapperProvider objectMapperProvider;
23+
private volatile ObjectMapper odinInputObjectMapper;
24+
private volatile ObjectMapper odinOutputObjectMapper;
25+
private volatile ObjectMapper jsonObjectMapper;
2526

2627
public MetaModel(ModelInfoLookup modelInfoLookup, BmmModel bmmModel) {
2728
this(modelInfoLookup, bmmModel, null);
@@ -38,15 +39,7 @@ public MetaModel(ModelInfoLookup modelInfoLookup, BmmModel bmmModel, AomProfile
3839
this.modelInfoLookup = modelInfoLookup;
3940
this.bmmModel = bmmModel;
4041
this.aomProfile = aomProfile;
41-
if (provider != null) {
42-
this.odinInputObjectMapper = provider.getInputOdinObjectMapper();
43-
this.odinOutputObjectMapper = provider.getOutputOdinObjectMapper();
44-
this.jsonObjectMapper = provider.getJsonObjectMapper();
45-
} else {
46-
this.odinInputObjectMapper = null;
47-
this.odinOutputObjectMapper = null;
48-
this.jsonObjectMapper = null;
49-
}
42+
this.objectMapperProvider = provider;
5043
}
5144

5245
/**
@@ -93,7 +86,17 @@ public AomProfile getAomProfile() {
9386
* @return the object mapper to use for JSON converted from ODIN to parse this model
9487
*/
9588
public ObjectMapper getOdinInputObjectMapper() {
96-
return odinInputObjectMapper;
89+
ObjectMapper mapper = odinInputObjectMapper;
90+
if (mapper == null && objectMapperProvider != null) {
91+
synchronized (this) {
92+
mapper = odinInputObjectMapper;
93+
if (mapper == null) {
94+
mapper = objectMapperProvider.getInputOdinObjectMapper();
95+
odinInputObjectMapper = mapper;
96+
}
97+
}
98+
}
99+
return mapper;
97100
}
98101

99102
/**
@@ -104,11 +107,31 @@ public ObjectMapper getOdinInputObjectMapper() {
104107
* @return Get the object mapper to output ODIN from this model
105108
*/
106109
public ObjectMapper getOdinOutputObjectMapper() {
107-
return odinOutputObjectMapper;
110+
ObjectMapper mapper = odinOutputObjectMapper;
111+
if (mapper == null && objectMapperProvider != null) {
112+
synchronized (this) {
113+
mapper = odinOutputObjectMapper;
114+
if (mapper == null) {
115+
mapper = objectMapperProvider.getOutputOdinObjectMapper();
116+
odinOutputObjectMapper = mapper;
117+
}
118+
}
119+
}
120+
return mapper;
108121
}
109122

110123
public ObjectMapper getJsonObjectMapper() {
111-
return jsonObjectMapper;
124+
ObjectMapper mapper = jsonObjectMapper;
125+
if (mapper == null && objectMapperProvider != null) {
126+
synchronized (this) {
127+
mapper = jsonObjectMapper;
128+
if (mapper == null) {
129+
mapper = objectMapperProvider.getJsonObjectMapper();
130+
jsonObjectMapper = mapper;
131+
}
132+
}
133+
}
134+
return mapper;
112135
}
113136

114137
/**
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.nedap.archie.rminfo;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import org.junit.jupiter.api.Test;
5+
import org.openehr.bmm.core.BmmModel;
6+
7+
import static org.junit.jupiter.api.Assertions.assertEquals;
8+
import static org.junit.jupiter.api.Assertions.assertNotNull;
9+
import static org.junit.jupiter.api.Assertions.assertNull;
10+
import static org.junit.jupiter.api.Assertions.assertSame;
11+
12+
public class MetaModelTest {
13+
14+
private static class CountingProvider implements RMObjectMapperProvider {
15+
int inputCalls;
16+
int outputCalls;
17+
int jsonCalls;
18+
19+
@Override
20+
public ObjectMapper getInputOdinObjectMapper() {
21+
inputCalls++;
22+
return new ObjectMapper();
23+
}
24+
25+
@Override
26+
public ObjectMapper getOutputOdinObjectMapper() {
27+
outputCalls++;
28+
return new ObjectMapper();
29+
}
30+
31+
@Override
32+
public ObjectMapper getJsonObjectMapper() {
33+
jsonCalls++;
34+
return new ObjectMapper();
35+
}
36+
}
37+
38+
@Test
39+
public void eachObjectMapperIsFetchedOnceAndCached() {
40+
CountingProvider provider = new CountingProvider();
41+
MetaModel metaModel = new MetaModel(null, new BmmModel(), null, provider);
42+
43+
metaModel.getOdinInputObjectMapper();
44+
assertEquals(1, provider.inputCalls);
45+
assertEquals(0, provider.outputCalls);
46+
assertEquals(0, provider.jsonCalls);
47+
48+
metaModel.getOdinOutputObjectMapper();
49+
assertEquals(1, provider.inputCalls);
50+
assertEquals(1, provider.outputCalls);
51+
assertEquals(0, provider.jsonCalls);
52+
53+
metaModel.getJsonObjectMapper();
54+
assertEquals(1, provider.inputCalls);
55+
assertEquals(1, provider.outputCalls);
56+
assertEquals(1, provider.jsonCalls);
57+
58+
metaModel.getOdinInputObjectMapper();
59+
metaModel.getOdinOutputObjectMapper();
60+
metaModel.getJsonObjectMapper();
61+
assertEquals(1, provider.inputCalls);
62+
assertEquals(1, provider.outputCalls);
63+
assertEquals(1, provider.jsonCalls);
64+
}
65+
}

0 commit comments

Comments
 (0)