Remove substitution string to use relative url, Fix client parser and custom extension.

This commit is contained in:
Sebastien Riviere 2017-02-08 11:14:19 +01:00
parent 3bf6555d61
commit c3447c3b4d
21 changed files with 542 additions and 25 deletions

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.context;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.*; import java.util.*;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
@ -100,9 +101,19 @@ public abstract class BaseRuntimeElementDefinition<T extends IBase> {
/** /**
* @return Returns null if none * @return Returns null if none
*/ */
public RuntimeChildDeclaredExtensionDefinition getDeclaredExtension(String theExtensionUrl) { public RuntimeChildDeclaredExtensionDefinition getDeclaredExtension(String theExtensionUrl, final String serverBaseUrl) {
validateSealed(); validateSealed();
return myUrlToExtension.get(theExtensionUrl); RuntimeChildDeclaredExtensionDefinition definition = myUrlToExtension.get(theExtensionUrl);
if (definition == null && StringUtils.isNotBlank(serverBaseUrl)) {
for (final Map.Entry<String, RuntimeChildDeclaredExtensionDefinition> entry : myUrlToExtension.entrySet()) {
final String key = (!UrlUtil.isValid(entry.getKey()) && StringUtils.isNotBlank(serverBaseUrl)) ? serverBaseUrl + entry.getKey() : entry.getKey();
if (key.equals(theExtensionUrl)) {
definition = entry.getValue();
break;
}
}
}
return definition;
} }
public List<RuntimeChildDeclaredExtensionDefinition> getExtensions() { public List<RuntimeChildDeclaredExtensionDefinition> getExtensions() {

View File

@ -115,7 +115,7 @@ public class ViewGenerator {
} }
private void addExtension(BaseRuntimeElementCompositeDefinition<?> theSourceDef, BaseElement theSource, BaseElement theTarget, RuntimeChildDeclaredExtensionDefinition nextExt, String url) { private void addExtension(BaseRuntimeElementCompositeDefinition<?> theSourceDef, BaseElement theSource, BaseElement theTarget, RuntimeChildDeclaredExtensionDefinition nextExt, String url) {
RuntimeChildDeclaredExtensionDefinition sourceDeclaredExt = theSourceDef.getDeclaredExtension(url); RuntimeChildDeclaredExtensionDefinition sourceDeclaredExt = theSourceDef.getDeclaredExtension(url, "");
if (sourceDeclaredExt == null) { if (sourceDeclaredExt == null) {
for (ExtensionDt next : theSource.getAllUndeclaredExtensions()) { for (ExtensionDt next : theSource.getAllUndeclaredExtensions()) {

View File

@ -77,6 +77,7 @@ import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.UrlUtil;
public abstract class BaseParser implements IParser { public abstract class BaseParser implements IParser {
@ -932,9 +933,17 @@ public abstract class BaseParser implements IParser {
} }
protected String getExtensionUrl(final String extensionUrl) { protected String getExtensionUrl(final String extensionUrl) {
return StringUtils.isNotBlank(extensionUrl) && StringUtils.isNotBlank(myServerBaseUrl) ? extensionUrl.replace("%BASE_SERVER_URL%", myServerBaseUrl) : extensionUrl; String url = extensionUrl;
if (StringUtils.isNotBlank(extensionUrl) && StringUtils.isNotBlank(myServerBaseUrl)) {
url = !UrlUtil.isValid(extensionUrl) && extensionUrl.startsWith("/") ? myServerBaseUrl + extensionUrl : extensionUrl;
}
return url;
} }
protected String getServerBaseUrl() {
return myServerBaseUrl;
}
/** /**
* Used for DSTU2 only * Used for DSTU2 only
*/ */

View File

@ -1407,7 +1407,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
} else { } else {
url = getExtensionUrl(jsonElement.getAsString()); url = getExtensionUrl(jsonElement.getAsString());
} }
theState.enteringNewElementExtension(null, url, theIsModifier); theState.enteringNewElementExtension(null, url, theIsModifier, getServerBaseUrl());
for (String next : nextExtObj.keySet()) { for (String next : nextExtObj.keySet()) {
if ("url".equals(next)) { if ("url".equals(next)) {
continue; continue;

View File

@ -98,8 +98,8 @@ class ParserState<T> {
myState.enteringNewElement(theNamespaceUri, theName); myState.enteringNewElement(theNamespaceUri, theName);
} }
public void enteringNewElementExtension(StartElement theElem, String theUrlAttr, boolean theIsModifier) { public void enteringNewElementExtension(StartElement theElem, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) {
myState.enteringNewElementExtension(theElem, theUrlAttr, theIsModifier); myState.enteringNewElementExtension(theElem, theUrlAttr, theIsModifier, baseServerUrl);
} }
public T getObject() { public T getObject() {
@ -791,7 +791,7 @@ class ParserState<T> {
* Default implementation just handles undeclared extensions * Default implementation just handles undeclared extensions
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) {
if (myPreResourceState != null && getCurrentElement() instanceof ISupportsUndeclaredExtensions) { if (myPreResourceState != null && getCurrentElement() instanceof ISupportsUndeclaredExtensions) {
ExtensionDt newExtension = new ExtensionDt(theIsModifier); ExtensionDt newExtension = new ExtensionDt(theIsModifier);
newExtension.setUrl(theUrlAttr); newExtension.setUrl(theUrlAttr);
@ -1483,7 +1483,7 @@ class ParserState<T> {
} }
@Override @Override
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) {
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr); RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr);
if (declaredExtension != null) { if (declaredExtension != null) {
if (myChildInstance == null) { if (myChildInstance == null) {
@ -1493,7 +1493,7 @@ class ParserState<T> {
BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myChildInstance); BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myChildInstance);
push(newState); push(newState);
} else { } else {
super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier); super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier, baseServerUrl);
} }
} }
@ -1664,13 +1664,13 @@ class ParserState<T> {
} }
@Override @Override
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) {
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getDeclaredExtension(theUrlAttr); RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getDeclaredExtension(theUrlAttr, baseServerUrl);
if (declaredExtension != null) { if (declaredExtension != null) {
BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myInstance); BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myInstance);
push(newState); push(newState);
} else { } else {
super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier); super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier, baseServerUrl);
} }
} }
@ -2466,7 +2466,7 @@ class ParserState<T> {
} }
@Override @Override
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) {
myDepth++; myDepth++;
} }

View File

@ -213,7 +213,7 @@ public class XmlParser extends BaseParser implements IParser {
} else { } else {
url = urlAttr.getValue(); url = urlAttr.getValue();
} }
parserState.enteringNewElementExtension(elem, url, false); parserState.enteringNewElementExtension(elem, url, false, getServerBaseUrl());
} else if ("modifierExtension".equals(elem.getName().getLocalPart())) { } else if ("modifierExtension".equals(elem.getName().getLocalPart())) {
Attribute urlAttr = elem.getAttributeByName(new QName("url")); Attribute urlAttr = elem.getAttributeByName(new QName("url"));
String url; String url;
@ -223,7 +223,7 @@ public class XmlParser extends BaseParser implements IParser {
} else { } else {
url = urlAttr.getValue(); url = urlAttr.getValue();
} }
parserState.enteringNewElementExtension(elem, url, true); parserState.enteringNewElementExtension(elem, url, true, getServerBaseUrl());
} else { } else {
String elementName = elem.getName().getLocalPart(); String elementName = elem.getName().getLocalPart();
parserState.enteringNewElement(namespaceURI, elementName); parserState.enteringNewElement(namespaceURI, elementName);

View File

@ -482,6 +482,7 @@ public abstract class BaseClient implements IRestfulClient {
throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader); throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
} }
IParser parser = respType.newParser(getFhirContext()); IParser parser = respType.newParser(getFhirContext());
parser.setServerBaseUrl(getUrlBase());
if (myPreferResponseTypes != null) { if (myPreferResponseTypes != null) {
parser.setPreferTypes(myPreferResponseTypes); parser.setPreferTypes(myPreferResponseTypes);
} }

View File

@ -179,7 +179,7 @@ public class ResourceParameter implements IParameter {
} }
IParser parser = encoding.newParser(ctx); IParser parser = encoding.newParser(ctx);
parser.setServerBaseUrl(theRequest.getFhirServerBase());
T retVal; T retVal;
try { try {
if (theResourceType != null) { if (theResourceType != null) {

View File

@ -56,17 +56,17 @@ public class ModelScannerDstu1Test {
assertEquals(RuntimeChildCompositeDatatypeDefinition.class, def.getChildByNameOrThrowDataFormatException("identifier").getClass()); assertEquals(RuntimeChildCompositeDatatypeDefinition.class, def.getChildByNameOrThrowDataFormatException("identifier").getClass());
RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1"); RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1", "");
assertNotNull(ext); assertNotNull(ext);
BaseRuntimeElementDefinition<?> valueString = ext.getChildByName("valueString"); BaseRuntimeElementDefinition<?> valueString = ext.getChildByName("valueString");
assertNotNull(valueString); assertNotNull(valueString);
ext = def.getDeclaredExtension("http://foo/#f2"); ext = def.getDeclaredExtension("http://foo/#f2", "");
assertNotNull(ext); assertNotNull(ext);
valueString = ext.getChildByName("valueString"); valueString = ext.getChildByName("valueString");
assertNotNull(valueString); assertNotNull(valueString);
ext = def.getDeclaredExtension("http://bar/#b1"); ext = def.getDeclaredExtension("http://bar/#b1", "");
assertNotNull(ext); assertNotNull(ext);
RuntimeChildDeclaredExtensionDefinition childExt = ext.getChildExtensionForUrl("http://bar/#b1/1"); RuntimeChildDeclaredExtensionDefinition childExt = ext.getChildExtensionForUrl("http://bar/#b1/1");
assertNotNull(childExt); assertNotNull(childExt);

View File

@ -1445,6 +1445,69 @@ public class JsonParserTest {
} }
@Test
public void testCustomUrlExtension() {
final String expected = "{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = jsonParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newJsonParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName());
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensioninBundle() {
final String expected = "{\"resourceType\":\"Bundle\",\"entry\":[{\"id\":null,\"content\":{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final Bundle bundle = new Bundle();
final BundleEntry entry = new BundleEntry();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = jsonParser.encodeBundleToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = jsonParser.parseBundle(parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
Patient newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = jsonParser.parseBundle(new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
ourCtx = FhirContext.forDstu1(); ourCtx = FhirContext.forDstu1();

View File

@ -0,0 +1,38 @@
package ca.uhn.fhir.parser;
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.ResourceDef;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.StringDt;
import java.util.ArrayList;
import java.util.List;
@ResourceDef()
public class MyPatientWithCustomUrlExtension extends Patient {
private static final long serialVersionUID = 1L;
@Child(name = "petName")
@Extension(url = "/petname", definedLocally = false, isModifier = false)
@Description(shortDefinition = "The name of the patient's favourite pet")
private StringDt myPetName;
public StringDt getPetName() {
return myPetName;
}
@Override
public boolean isEmpty() {
return super.isEmpty() && myPetName.isEmpty();
}
public void setPetName(StringDt thePetName) {
myPetName = thePetName;
}
}

View File

@ -1997,6 +1997,69 @@ public class XmlParserTest {
assertEquals(15, bundleR.getTotalResults().getValue().intValue()); assertEquals(15, bundleR.getTotalResults().getValue().intValue());
} }
@Test
public void testCustomUrlExtension() {
final String expected = "<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = xmlParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newXmlParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName());
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensioninBundle() {
final String expected = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id/><entry><id/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient></content></entry></feed>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final Bundle bundle = new Bundle();
final BundleEntry entry = new BundleEntry();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = xmlParser.encodeBundleToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = xmlParser.parseBundle(parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
Patient newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = xmlParser.parseBundle(new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
XMLUnit.setIgnoreAttributeOrder(true); XMLUnit.setIgnoreAttributeOrder(true);

View File

@ -14,7 +14,7 @@ public class CustomPatientDstu2 extends Patient {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Child(name = "homeless", order = 1) @Child(name = "homeless", order = 1)
@Extension(url = "%BASE_SERVER_URL%/StructureDefinition/homeless", definedLocally = true, isModifier = false) @Extension(url = "/StructureDefinition/homeless", definedLocally = true, isModifier = false)
@Description(shortDefinition = "The patient being homeless, true if homeless") @Description(shortDefinition = "The patient being homeless, true if homeless")
private BooleanDt homeless; private BooleanDt homeless;

View File

@ -16,6 +16,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader;
import java.util.*; import java.util.*;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@ -1933,4 +1934,70 @@ public class JsonParserDstu2Test {
assertTrue(parsedPatient.contains("http://myserver.com/StructureDefinition/Patient")); assertTrue(parsedPatient.contains("http://myserver.com/StructureDefinition/Patient"));
assertTrue(parsedPatient.contains("http://myserver.com/StructureDefinition/homeless")); assertTrue(parsedPatient.contains("http://myserver.com/StructureDefinition/homeless"));
} }
/**
* Test for the url generated based on the server config
*/
@Test
public void testCustomUrlExtension() {
final String expected = "{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = jsonParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newJsonParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName());
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensioninBundle() {
final String expected = "{\"resourceType\":\"Bundle\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final Bundle bundle = new Bundle();
final BundleEntry entry = new BundleEntry();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = jsonParser.encodeBundleToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = jsonParser.parseBundle(parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
Patient newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = jsonParser.parseBundle(new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
} }

View File

@ -0,0 +1,33 @@
package ca.uhn.fhir.parser;
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.ResourceDef;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.StringDt;
@ResourceDef()
public class MyPatientWithCustomUrlExtension extends Patient {
private static final long serialVersionUID = 1L;
@Child(name = "petName")
@Extension(url = "/petname", definedLocally = false, isModifier = false)
@Description(shortDefinition = "The name of the patient's favourite pet")
private StringDt myPetName;
public StringDt getPetName() {
return myPetName;
}
public void setPetName(StringDt thePetName) {
myPetName = thePetName;
}
@Override
public boolean isEmpty() {
return super.isEmpty() && myPetName.isEmpty();
}
}

View File

@ -2745,6 +2745,72 @@ public class XmlParserDstu2Test {
assertTrue(parsedPatient.contains("<extension url=\"http://myserver.com/StructureDefinition/homeless\">")); assertTrue(parsedPatient.contains("<extension url=\"http://myserver.com/StructureDefinition/homeless\">"));
} }
/**
* Test for the url generated based on the server config
*/
@Test
public void testCustomUrlExtension() {
final String expected = "<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = xmlParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newXmlParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName());
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensionInBundle() {
final String expected = "<Bundle xmlns=\"http://hl7.org/fhir\"><entry><resource><Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient></resource></entry></Bundle>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final Bundle bundle = new Bundle();
final BundleEntry entry = new BundleEntry();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = xmlParser.encodeBundleToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = xmlParser.parseBundle(parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
Patient newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = xmlParser.parseBundle(new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@AfterClass @AfterClass
public static void afterClassClearContext() { public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest(); TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -81,17 +81,17 @@ public class ModelScannerDstu3Test {
assertEquals(RuntimeChildCompositeDatatypeDefinition.class, def.getChildByNameOrThrowDataFormatException("identifier").getClass()); assertEquals(RuntimeChildCompositeDatatypeDefinition.class, def.getChildByNameOrThrowDataFormatException("identifier").getClass());
RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1"); RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1", "");
assertNotNull(ext); assertNotNull(ext);
BaseRuntimeElementDefinition<?> valueString = ext.getChildByName("valueString"); BaseRuntimeElementDefinition<?> valueString = ext.getChildByName("valueString");
assertNotNull(valueString); assertNotNull(valueString);
ext = def.getDeclaredExtension("http://foo/#f2"); ext = def.getDeclaredExtension("http://foo/#f2", "");
assertNotNull(ext); assertNotNull(ext);
valueString = ext.getChildByName("valueString"); valueString = ext.getChildByName("valueString");
assertNotNull(valueString); assertNotNull(valueString);
ext = def.getDeclaredExtension("http://bar/#b1"); ext = def.getDeclaredExtension("http://bar/#b1", "");
assertNotNull(ext); assertNotNull(ext);
RuntimeChildDeclaredExtensionDefinition childExt = ext.getChildExtensionForUrl("http://bar/#b1/1"); RuntimeChildDeclaredExtensionDefinition childExt = ext.getChildExtensionForUrl("http://bar/#b1/1");
assertNotNull(childExt); assertNotNull(childExt);

View File

@ -14,7 +14,7 @@ public class CustomPatientDstu3 extends Patient {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Child(name = "homeless", order = 1) @Child(name = "homeless", order = 1)
@Extension(url = "%BASE_SERVER_URL%/StructureDefinition/homeless", definedLocally = true, isModifier = false) @Extension(url = "/StructureDefinition/homeless", definedLocally = true, isModifier = false)
@Description(shortDefinition = "The patient being homeless, true if homeless") @Description(shortDefinition = "The patient being homeless, true if homeless")
private BooleanType homeless; private BooleanType homeless;

View File

@ -22,6 +22,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
@ -2169,6 +2170,72 @@ public class JsonParserDstu3Test {
assertTrue(result.isSuccessful()); assertTrue(result.isSuccessful());
} }
/**
* Test for the url generated based on the server config
*/
@Test
public void testCustomUrlExtension() {
final String expected = "{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringType("myName"));
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = jsonParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = jsonParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newJsonParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName());
assertEquals("myName", ((StringType) newPatient.getExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensioninBundle() {
final String expected = "{\"resourceType\":\"Bundle\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://www.example.com/petname\",\"valueString\":\"myName\"}]}}]}";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringType("myName"));
final Bundle bundle = new Bundle();
final BundleEntryComponent entry = new BundleEntryComponent();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser jsonParser = ourCtx.newJsonParser();
jsonParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = jsonParser.encodeResourceToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = jsonParser.parseResource(Bundle.class, parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntry().size());
Patient newPatient = (Patient) newBundle.getEntry().get(0).getResource();
assertEquals("myName", ((StringType) newPatient.getExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = jsonParser.parseResource(Bundle.class, new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntry().size());
newPatient = (Patient) newBundle.getEntry().get(0).getResource();
assertEquals("myName", ((StringType) newPatient.getExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@AfterClass @AfterClass
public static void afterClassClearContext() { public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest(); TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -0,0 +1,33 @@
package ca.uhn.fhir.parser;
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.ResourceDef;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.Patient;
@ResourceDef()
public class MyPatientWithCustomUrlExtension extends Patient {
private static final long serialVersionUID = 1L;
@Child(name = "petName")
@Extension(url = "/petname", definedLocally = false, isModifier = false)
@Description(shortDefinition = "The name of the patient's favourite pet")
private StringType myPetName;
public StringType getPetName() {
return myPetName;
}
public void setPetName(final StringType thePetName) {
myPetName = thePetName;
}
@Override
public boolean isEmpty() {
return super.isEmpty() && myPetName.isEmpty();
}
}

View File

@ -3184,6 +3184,72 @@ public class XmlParserDstu3Test {
assertTrue(parsedPatient.contains("<extension url=\"http://myserver.com/StructureDefinition/homeless\">")); assertTrue(parsedPatient.contains("<extension url=\"http://myserver.com/StructureDefinition/homeless\">"));
} }
/**
* Test for the url generated based on the server config
*/
@Test
public void testCustomUrlExtension() {
final String expected = "<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringType("myName"));
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = xmlParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newXmlParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName());
assertEquals("myName", ((StringType) newPatient.getExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensioninBundle() {
final String expected = "<Bundle xmlns=\"http://hl7.org/fhir\"><entry><resource><Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient></resource></entry></Bundle>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringType("myName"));
final Bundle bundle = new Bundle();
final BundleEntryComponent entry = new BundleEntryComponent();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = xmlParser.encodeResourceToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = xmlParser.parseResource(Bundle.class, parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntry().size());
Patient newPatient = (Patient) newBundle.getEntry().get(0).getResource();
assertEquals("myName", ((StringType) newPatient.getExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = xmlParser.parseResource(Bundle.class, new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntry().size());
newPatient = (Patient) newBundle.getEntry().get(0).getResource();
assertEquals("myName", ((StringType) newPatient.getExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@AfterClass @AfterClass
public static void afterClassClearContext() { public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest(); TestUtil.clearAllStaticFieldsForUnitTest();