Skip to content
This repository was archived by the owner on Mar 5, 2026. It is now read-only.

Commit f0396f5

Browse files
authored
Merge pull request #169 from medblocks/160_properly-working-with-context-start
#160: honoring context.start when mapping
2 parents b5329c5 + fa93eec commit f0396f5

6 files changed

Lines changed: 135 additions & 34 deletions

File tree

src/main/java/com/medblocks/openfhir/ProdOpenFhirMappingContext.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ public void initMappingCache(final FhirConnectContext context,
8989
fhirContextRepo.setMappers(mappers);
9090
fhirContextRepo.setSlotMappers(slotMappers);
9191

92+
final String start = context.getContext().getStart();
93+
if (start != null) {
94+
final List<OpenFhirFhirConnectModelMapper> archetypeMappers = mappers.get(start);
95+
if (archetypeMappers == null) {
96+
context.getContext().setStart(start);
97+
} else {
98+
final String overridenMapper = archetypeMappers.get(0).getOpenEhrConfig()
99+
.getArchetype();
100+
context.getContext().setStart(overridenMapper);
101+
}
102+
}
103+
92104
repository.put(normalizedRepoId, fhirContextRepo);
93105
}
94106

src/main/java/com/medblocks/openfhir/tofhir/OpenEhrToFhir.java

Lines changed: 107 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,57 @@ public Bundle compositionToFhir(final FhirConnectContext context,
164164
final Set<String> createdAndAdded = new HashSet<>();
165165
final Set<String> archetypesAlreadyProcessed = new HashSet<>();
166166

167-
// first the parent itself
168-
// get mapper by templateid (context) + archetype id (model)
167+
if (StringUtils.isEmpty(context.getContext().getStart())
168+
|| context.getContext().getStart().equals(composition.getArchetypeNodeId())) {
169+
// fallback to the previous logic
170+
// first the parent itself
171+
// get mapper by templateid (context) + archetype id (model)
172+
handleParentCompositionMapping(webTemplate, templateId, creatingBundle, flatJsonObject,
173+
archetypesAlreadyProcessed, isMultipleByResourceType,
174+
intermediateCaches,
175+
createdAndAdded, composition);
176+
177+
// all content
178+
handleContentCompositionsMapping(webTemplate, templateId, creatingBundle, flatJsonObject,
179+
archetypesAlreadyProcessed, isMultipleByResourceType,
180+
intermediateCaches,
181+
createdAndAdded, composition);
182+
} else {
183+
// find where to start
184+
final ContentItem startingContentItem = composition.getContent().stream()
185+
.filter(c -> c.getArchetypeNodeId().equals(context.getContext().getStart()))
186+
.findAny().orElse(null);
187+
if (startingContentItem == null) {
188+
final String availableStarts = composition.getContent().stream().map(c -> c.getArchetypeNodeId())
189+
.collect(Collectors.joining(", "));
190+
log.error(
191+
"context.start archetype '{}' not found within composition content. Available starts are: {}",
192+
context.getContext().getStart(), availableStarts);
193+
return creatingBundle;
194+
}
195+
handleContentItemMapping(webTemplate,
196+
templateId,
197+
creatingBundle,
198+
flatJsonObject,
199+
archetypesAlreadyProcessed,
200+
isMultipleByResourceType,
201+
intermediateCaches,
202+
createdAndAdded,
203+
startingContentItem);
204+
}
205+
206+
return creatingBundle;
207+
}
208+
209+
private void handleParentCompositionMapping(final WebTemplate webTemplate,
210+
final String templateId,
211+
final Bundle creatingBundle,
212+
final JsonObject flatJsonObject,
213+
final Set<String> archetypesAlreadyProcessed,
214+
final Map<String, Boolean> isMultipleByResourceType,
215+
final Map<String, Map<String, Object>> intermediateCaches,
216+
final Set<String> createdAndAdded,
217+
final Composition composition) {
169218
final List<OpenFhirFhirConnectModelMapper> parentMappers = openFhirTemplateRepo.getMapperForArchetype(
170219
templateId, composition.getArchetypeNodeId());
171220
if (parentMappers != null) {
@@ -181,41 +230,68 @@ public Bundle compositionToFhir(final FhirConnectContext context,
181230
composition.getArchetypeNodeId(),
182231
true);
183232
}
233+
}
184234

235+
private void handleContentCompositionsMapping(final WebTemplate webTemplate,
236+
final String templateId,
237+
final Bundle creatingBundle,
238+
final JsonObject flatJsonObject,
239+
final Set<String> archetypesAlreadyProcessed,
240+
final Map<String, Boolean> isMultipleByResourceType,
241+
final Map<String, Map<String, Object>> intermediateCaches,
242+
final Set<String> createdAndAdded,
243+
final Composition composition) {
185244
// loop through top level content/archetypes within the Composition
186245
for (final ContentItem archetypesWithinContent : composition.getContent()) {
246+
handleContentItemMapping(webTemplate,
247+
templateId,
248+
creatingBundle,
249+
flatJsonObject,
250+
archetypesAlreadyProcessed,
251+
isMultipleByResourceType,
252+
intermediateCaches,
253+
createdAndAdded,
254+
archetypesWithinContent);
255+
}
256+
}
187257

188-
// elements instantiated throughout the mapping (FHIR dataelements instantiated, key'd by created object + fhir path + openehr path)
189-
// instanced here so multiple archetypes can share them
190-
final Map<String, Object> instantiatedIntermediateElements = new HashMap<>();
191-
192-
final String archetypeNodeId = archetypesWithinContent.getArchetypeNodeId();
193-
if (archetypesAlreadyProcessed.contains(archetypeNodeId)) {
194-
continue;
195-
}
196-
197-
// get mapper by templateid (context) + archetype id (model)
198-
final List<OpenFhirFhirConnectModelMapper> theMappers = openFhirTemplateRepo.getMapperForArchetype(
199-
templateId, archetypeNodeId);
200-
if (theMappers == null) {
201-
log.error("No mappers defined for archetype within this composition: {}. No mapping possible.",
202-
archetypeNodeId);
203-
continue;
204-
}
205-
handleMappings(theMappers,
206-
createdAndAdded,
207-
intermediateCaches,
208-
isMultipleByResourceType,
209-
flatJsonObject,
210-
webTemplate,
211-
instantiatedIntermediateElements,
212-
creatingBundle,
213-
archetypesAlreadyProcessed,
214-
archetypeNodeId,
215-
false);
258+
private void handleContentItemMapping(final WebTemplate webTemplate,
259+
final String templateId,
260+
final Bundle creatingBundle,
261+
final JsonObject flatJsonObject,
262+
final Set<String> archetypesAlreadyProcessed,
263+
final Map<String, Boolean> isMultipleByResourceType,
264+
final Map<String, Map<String, Object>> intermediateCaches,
265+
final Set<String> createdAndAdded,
266+
final ContentItem archetypesWithinContent) {
267+
// elements instantiated throughout the mapping (FHIR dataelements instantiated, key'd by created object + fhir path + openehr path)
268+
// instanced here so multiple archetypes can share them
269+
final Map<String, Object> instantiatedIntermediateElements = new HashMap<>();
270+
271+
final String archetypeNodeId = archetypesWithinContent.getArchetypeNodeId();
272+
if (archetypesAlreadyProcessed.contains(archetypeNodeId)) {
273+
return;
216274
}
217275

218-
return creatingBundle;
276+
// get mapper by templateid (context) + archetype id (model)
277+
final List<OpenFhirFhirConnectModelMapper> theMappers = openFhirTemplateRepo.getMapperForArchetype(
278+
templateId, archetypeNodeId);
279+
if (theMappers == null) {
280+
log.error("No mappers defined for archetype within this composition: {}. No mapping possible.",
281+
archetypeNodeId);
282+
return;
283+
}
284+
handleMappings(theMappers,
285+
createdAndAdded,
286+
intermediateCaches,
287+
isMultipleByResourceType,
288+
flatJsonObject,
289+
webTemplate,
290+
instantiatedIntermediateElements,
291+
creatingBundle,
292+
archetypesAlreadyProcessed,
293+
archetypeNodeId,
294+
false);
219295
}
220296

221297
/**

src/test/java/com/medblocks/openfhir/TestOpenFhirMappingContext.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ private Map<String, List<OpenFhirFhirConnectModelMapper>> loadMappings(final Fil
135135
}
136136
});
137137

138+
final String start = context.getContext().getStart();
139+
if (start != null) {
140+
final List<OpenFhirFhirConnectModelMapper> archetypeMappers = mappers.get(start);
141+
if (archetypeMappers == null) {
142+
context.getContext().setStart(start);
143+
} else {
144+
final String overridenMapper = archetypeMappers.get(0).getOpenEhrConfig()
145+
.getArchetype();
146+
context.getContext().setStart(overridenMapper);
147+
}
148+
}
149+
150+
138151
return mappers;
139152
}
140153

src/test/resources/growth_chart/growth-chart.context.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ context:
1717
- "OBSERVATION.height.v2"
1818
- "OBSERVATION.body_mass_index.v2"
1919
- "OBSERVATION.head_circumference.v1"
20-
start: "OBSERVATION.body_weight.v2"
20+
start: "openEHR-EHR-COMPOSITION.growth_chart.v0"

src/test/resources/news2/NEWS2_Context_Mapping.context.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ context:
2020
- "OBSERVATION.pulse.v2"
2121
- "OBSERVATION.respiration.v2"
2222
- "OBSERVATION.pulse_oximetry.v1"
23-
start: "OBSERVATION.news2.v1"
23+
start: "openEHR-EHR-COMPOSITION.encounter.v1"

src/test/resources/rso_poc_acp/acp-poc.context.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ context:
1818
- "OBSERVATION.karnofsky_performance_status_scale.v1"
1919
- "EVALUATION.clinical_synopsis.v1"
2020
- "CLUSTER.media_file.v1"
21-
start: "EVALUATION.advance_care_directive.v2"
21+
start: "openEHR-EHR-COMPOSITION.report.v1"

0 commit comments

Comments
 (0)