From 1501b3e278482188e86e1b40b8ff35a43cae6956 Mon Sep 17 00:00:00 2001 From: "b.debeaubien" Date: Fri, 12 Dec 2014 11:42:14 -0500 Subject: [PATCH] #59 - Start of sorting out profile vs id problem --- .../context/RuntimeResourceDefinition.java | 21 +++++++ .../uhn/fhir/rest/server/RestfulServer.java | 24 +++++--- .../RuntimeResourceDefinitionTest.java | 59 ++++++++++++++++--- 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java index f357bd32f97..42c8ce1532f 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java @@ -30,6 +30,7 @@ import java.util.Map; import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.annotation.ResourceDef; +import com.phloc.commons.url.URLValidator; public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefinition { @@ -74,10 +75,30 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini return ChildTypeEnum.RESOURCE; } + @Deprecated public String getResourceProfile() { return myResourceProfile; } + public String getResourceProfile(String theServerBase) { + String profile; + if (!myResourceProfile.isEmpty()) { + profile = myResourceProfile; + } else if (!myId.isEmpty()) { + profile = myId; + } else { + return ""; + } + + if (!URLValidator.isValid(profile)) { + String profileWithUrl = theServerBase + "/Profile/" + profile; + if (URLValidator.isValid(profileWithUrl)) { + return profileWithUrl; + } + } + return profile; + } + public RuntimeSearchParam getSearchParam(String theName) { return myNameToSearchParam.get(theName); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java index c8c448bd7e6..29bebcd146b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java @@ -469,11 +469,7 @@ public class RestfulServer extends HttpServlet { requestPath = requestPath.substring(1); } - fhirServerBase = myServerAddressStrategy.determineServerBase(getServletContext(), theRequest); - - if (fhirServerBase.endsWith("/")) { - fhirServerBase = fhirServerBase.substring(0, fhirServerBase.length() - 1); - } + fhirServerBase = determineServerBase(theRequest); String completeUrl = StringUtils.isNotBlank(theRequest.getQueryString()) ? requestUrl + "?" + theRequest.getQueryString() : requestUrl.toString(); @@ -710,6 +706,16 @@ public class RestfulServer extends HttpServlet { } + private String determineServerBase(HttpServletRequest theRequest) { + String fhirServerBase; + fhirServerBase = myServerAddressStrategy.determineServerBase(getServletContext(), theRequest); + + if (fhirServerBase.endsWith("/")) { + fhirServerBase = fhirServerBase.substring(0, fhirServerBase.length() - 1); + } + return fhirServerBase; + } + /** * Initializes the server. Note that this method is final to avoid accidentally introducing bugs in implementations, but subclasses may put initialization code in {@link #initialize()}, which is * called immediately before beginning initialization of the restful server's internal init. @@ -944,7 +950,7 @@ public class RestfulServer extends HttpServlet { myInterceptors.remove(theInterceptor); } - private static void addProfileToBundleEntry(FhirContext theContext, IResource theResource) { + private static void addProfileToBundleEntry(FhirContext theContext, IResource theResource, String theServerBase) { TagList tl = ResourceMetadataKeyEnum.TAG_LIST.get(theResource); if (tl == null) { @@ -953,7 +959,7 @@ public class RestfulServer extends HttpServlet { } RuntimeResourceDefinition nextDef = theContext.getResourceDefinition(theResource); - String profile = nextDef.getResourceProfile(); + String profile = nextDef.getResourceProfile(theServerBase); if (isNotBlank(profile)) { tl.add(new Tag(Tag.HL7_ORG_PROFILE_TAG, profile, null)); } @@ -1017,7 +1023,7 @@ public class RestfulServer extends HttpServlet { for (IResource nextRes : resourceList) { RuntimeResourceDefinition def = theServer.getFhirContext().getResourceDefinition(nextRes); if (theServer.getAddProfileTag() == AddProfileTagEnum.ALWAYS || !def.isStandardProfile()) { - addProfileToBundleEntry(theServer.getFhirContext(), nextRes); + addProfileToBundleEntry(theServer.getFhirContext(), nextRes, theServerBase); } } } @@ -1336,7 +1342,7 @@ public class RestfulServer extends HttpServlet { if (theServer.getAddProfileTag() != AddProfileTagEnum.NEVER) { RuntimeResourceDefinition def = theServer.getFhirContext().getResourceDefinition(theResource); if (theServer.getAddProfileTag() == AddProfileTagEnum.ALWAYS || !def.isStandardProfile()) { - addProfileToBundleEntry(theServer.getFhirContext(), theResource); + addProfileToBundleEntry(theServer.getFhirContext(), theResource, theServerBase); } } diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/RuntimeResourceDefinitionTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/RuntimeResourceDefinitionTest.java index 68caf6d83fa..cb53f1a8df2 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/RuntimeResourceDefinitionTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/RuntimeResourceDefinitionTest.java @@ -1,11 +1,6 @@ package ca.uhn.fhir.context; -import static org.junit.Assert.*; - -import java.util.List; - -import org.junit.Test; - +import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.model.dstu.resource.Patient; import ca.uhn.fhir.model.dstu.resource.Profile; import ca.uhn.fhir.model.dstu.resource.Profile.ExtensionDefn; @@ -13,6 +8,12 @@ import ca.uhn.fhir.model.dstu.resource.Profile.Structure; import ca.uhn.fhir.model.dstu.resource.Profile.StructureElement; import ca.uhn.fhir.model.dstu.resource.ValueSet; import ca.uhn.fhir.model.dstu.valueset.DataTypeEnum; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class RuntimeResourceDefinitionTest { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RuntimeResourceDefinitionTest.class); @@ -58,7 +59,7 @@ public class RuntimeResourceDefinitionTest { Profile profile = (Profile) def.toProfile(); - ourLog.info(ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(profile)); + ourLog.info(ctx.newXmlParser().encodeResourceToString(profile)); List element = profile.getStructure().get(0).getElement(); assertEquals(1, element.get(0).getDefinition().getType().size()); @@ -102,4 +103,48 @@ public class RuntimeResourceDefinitionTest { assertEquals("customobservation", profile.getId().toString()); } + @Test + public void whenResourceProfileNotSet_ProfileShouldBeConstructedFromServerBaseAndId() { + FhirContext ctx = new FhirContext(PatientSansProfile.class); + RuntimeResourceDefinition def = ctx.getResourceDefinition(PatientSansProfile.class); + assertEquals("http://foo.org/fhir/Profile/PatientSansProfile", def.getResourceProfile("http://foo.org/fhir")); + } + + @ResourceDef(name = "Patient", id = "PatientSansProfile") + class PatientSansProfile extends Patient { + } + + @Test + public void whenResourceProfileHasNoUrl_ProfileShouldBeConstructedFromServerBaseAndProfile() { + FhirContext ctx = new FhirContext(PatientWithShortProfile.class); + RuntimeResourceDefinition def = ctx.getResourceDefinition(PatientWithShortProfile.class); + assertEquals("http://foo.org/fhir/Profile/PatientWithShortProfile", def.getResourceProfile("http://foo.org/fhir")); + } + + @ResourceDef(name = "Patient", id = "PatientWithShortProfileId", profile="PatientWithShortProfile") + class PatientWithShortProfile extends Patient { + } + + @Test + public void whenResourceProfileHasUrl_ProfileShouldUseThat() { + FhirContext ctx = new FhirContext(PatientWithFullProfile.class); + RuntimeResourceDefinition def = ctx.getResourceDefinition(PatientWithFullProfile.class); + assertEquals("http://bar.org/Profile/PatientWithFullProfile", def.getResourceProfile("http://foo.org/fhir")); + } + + @ResourceDef(name = "Patient", id = "PatientWithFullProfileId", profile="http://bar.org/Profile/PatientWithFullProfile") + class PatientWithFullProfile extends Patient { + } + + @Test + public void whenProfileAndIdAreBlank_ProfileShouldBeBlank() { + FhirContext ctx = new FhirContext(PatientWithNoIdOrProfile.class); + RuntimeResourceDefinition def = ctx.getResourceDefinition(PatientWithNoIdOrProfile.class); + assertEquals("", def.getResourceProfile("http://foo.org/fhir")); + } + + @ResourceDef(name = "Patient") + class PatientWithNoIdOrProfile extends Patient { + } + }