From 8ac479b7bd5bf57864bae68f94b68ae2d908ac83 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Wed, 10 Dec 2014 10:40:29 -0500 Subject: [PATCH] Prevent profile generation issue with multiple resource definition classes that share an extension --- .../ca/uhn/fhir/model/dstu/FhirDstu1.java | 18 +-- .../fhir/context/DuplicateExtensionTest.java | 115 ++++++++++-------- 2 files changed, 74 insertions(+), 59 deletions(-) diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/model/dstu/FhirDstu1.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/model/dstu/FhirDstu1.java index 07765b9beaa..81158f84644 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/model/dstu/FhirDstu1.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/model/dstu/FhirDstu1.java @@ -33,6 +33,7 @@ import java.util.Map; import ca.uhn.fhir.context.*; import ca.uhn.fhir.model.api.ICompositeDatatype; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; @@ -57,7 +58,7 @@ import ca.uhn.fhir.rest.server.provider.ServerProfileProvider; public class FhirDstu1 implements IFhirVersion { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirDstu1.class); - private Map myExtensionDefToCode = new HashMap(); +// private Map myExtensionDefToCode = new HashMap(); private String myId; @Override @@ -158,7 +159,7 @@ public class FhirDstu1 implements IFhirVersion { String expectedPath = StringUtils.join(path, '.'); - ourLog.info("Filling profile for: {} - Path: {}", expectedPath); + ourLog.debug("Filling profile for: {} - Path: {}", expectedPath); String name = def.getName(); if (!expectedPath.equals(name)) { path.pollLast(); @@ -267,11 +268,12 @@ public class FhirDstu1 implements IFhirVersion { return retVal; } - private void scanForExtensions(Profile theProfile, BaseRuntimeElementDefinition def) { + private Map scanForExtensions(Profile theProfile, BaseRuntimeElementDefinition def) { BaseRuntimeElementCompositeDefinition cdef = ((BaseRuntimeElementCompositeDefinition) def); + Map extensionDefToCode = new HashMap(); for (RuntimeChildDeclaredExtensionDefinition nextChild : cdef.getExtensions()) { - if (myExtensionDefToCode.containsKey(nextChild)) { + if (extensionDefToCode.containsKey(nextChild)) { continue; } @@ -288,10 +290,10 @@ public class FhirDstu1 implements IFhirVersion { } defn.setCode(code); - if (myExtensionDefToCode.values().contains(code)) { + if (extensionDefToCode.values().contains(code)) { throw new IllegalStateException("Duplicate extension code: " + code); } - myExtensionDefToCode.put(nextChild, code); + extensionDefToCode.put(nextChild, code); if (nextChild.getChildType() != null && IPrimitiveDatatype.class.isAssignableFrom(nextChild.getChildType())) { RuntimePrimitiveDatatypeDefinition pdef = (RuntimePrimitiveDatatypeDefinition) nextChild.getSingleChildOrThrow(); @@ -306,11 +308,13 @@ public class FhirDstu1 implements IFhirVersion { for (RuntimeChildDeclaredExtensionDefinition nextChildExt : pdef.getExtensions()) { StructureElementDefinitionType type = defn.getDefinition().addType(); type.setCode(DataTypeEnum.EXTENSION); - type.setProfile("#" + myExtensionDefToCode.get(nextChildExt)); + type.setProfile("#" + extensionDefToCode.get(nextChildExt)); } } } + + return extensionDefToCode; } @Override diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/DuplicateExtensionTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/DuplicateExtensionTest.java index a09371ed927..a391d4214c0 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/DuplicateExtensionTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/DuplicateExtensionTest.java @@ -1,71 +1,82 @@ package ca.uhn.fhir.context; -import ca.uhn.fhir.model.api.annotation.*; +import junit.framework.TestCase; + +import org.junit.Test; + +import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.api.annotation.Child; +import ca.uhn.fhir.model.api.annotation.Description; +import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.model.api.annotation.ProvidesResources; +import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.model.dstu.resource.Observation; import ca.uhn.fhir.model.dstu.resource.Patient; -import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.model.dstu.resource.Profile; import ca.uhn.fhir.model.primitive.StringDt; -import junit.framework.TestCase; -import org.junit.Ignore; -import org.junit.Test; /** * Created by Bill de Beaubien on 12/10/2014. */ public class DuplicateExtensionTest extends TestCase { - @Test - public void testScannerShouldAddProvidedResources() { -// FhirContext ctx = new FhirContext(); -// RuntimeResourceDefinition patientDef = ctx.getResourceDefinition(CustomPatient.class); -// patientDef.toProfile(); -// -// RuntimeResourceDefinition observationDef = ctx.getResourceDefinition(CustomObservation.class); -// observationDef.toProfile(); - } + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DuplicateExtensionTest.class); + + @Test + public void testScannerShouldAddProvidedResources() { + FhirContext ctx = new FhirContext(); + RuntimeResourceDefinition patientDef = ctx.getResourceDefinition(CustomPatient.class); + Profile profile = (Profile) patientDef.toProfile(); - @ProvidesResources(resources = CustomObservation.class) - class CustomObservationProvider { - } + String res = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(profile); + ourLog.info(res); + + RuntimeResourceDefinition observationDef = ctx.getResourceDefinition(CustomObservation.class); + profile = (Profile) observationDef.toProfile(); + } - @ProvidesResources(resources = CustomPatient.class) - class CustomPatientProvider { - } + @ResourceDef(name = "Observation", id = "CustomObservation") + class CustomObservation extends Observation { + @Child(name = "idExt", order = 0) + @Extension(url = "http://foo.org#id", definedLocally = true, isModifier = false) + @Description(shortDefinition = "Contains the id of the resource") + private StringDt myIdExt; - @ResourceDef(name = "Patient", id = "CustomPatient") - class CustomPatient extends Patient { - @Child(name="idExt", order = 0) - @Extension(url= "http://foo.org#id", definedLocally=true, isModifier=false) - @Description(shortDefinition = "Contains the id of the resource") - private StringDt myIdExt; + public StringDt getIdExt() { + if (myIdExt == null) { + myIdExt = new StringDt(); + } + return myIdExt; + } - public StringDt getIdExt() { - if (myIdExt == null) { - myIdExt = new StringDt(); - } - return myIdExt; - } + public void setIdExt(StringDt theIdExt) { + myIdExt = theIdExt; + } + } - public void setIdExt(StringDt theIdExt) { - myIdExt = theIdExt; - } - } + @ProvidesResources(resources = CustomObservation.class) + class CustomObservationProvider { + } - @ResourceDef(name = "Observation", id = "CustomObservation") - class CustomObservation extends Observation { - @Child(name="idExt", order = 0) - @Extension(url= "http://foo.org#id", definedLocally=true, isModifier=false) - @Description(shortDefinition = "Contains the id of the resource") - private StringDt myIdExt; + @ResourceDef(name = "Patient", id = "CustomPatient") + class CustomPatient extends Patient { + @Child(name = "idExt", order = 0) + @Extension(url = "http://foo.org#id", definedLocally = true, isModifier = false) + @Description(shortDefinition = "Contains the id of the resource") + private StringDt myIdExt; - public StringDt getIdExt() { - if (myIdExt == null) { - myIdExt = new StringDt(); - } - return myIdExt; - } + public StringDt getIdExt() { + if (myIdExt == null) { + myIdExt = new StringDt(); + } + return myIdExt; + } - public void setIdExt(StringDt theIdExt) { - myIdExt = theIdExt; - } - } + public void setIdExt(StringDt theIdExt) { + myIdExt = theIdExt; + } + } + + @ProvidesResources(resources = CustomPatient.class) + class CustomPatientProvider { + } }