diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java index 3121a8ad1ae..2390a569e40 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java @@ -22,6 +22,7 @@ package ca.uhn.fhir.context; import java.lang.reflect.Constructor; import java.util.*; +import ca.uhn.fhir.util.UrlUtil; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBase; @@ -100,9 +101,19 @@ public abstract class BaseRuntimeElementDefinition { /** * @return Returns null if none */ - public RuntimeChildDeclaredExtensionDefinition getDeclaredExtension(String theExtensionUrl) { + public RuntimeChildDeclaredExtensionDefinition getDeclaredExtension(String theExtensionUrl, final String serverBaseUrl) { validateSealed(); - return myUrlToExtension.get(theExtensionUrl); + RuntimeChildDeclaredExtensionDefinition definition = myUrlToExtension.get(theExtensionUrl); + if (definition == null && StringUtils.isNotBlank(serverBaseUrl)) { + for (final Map.Entry 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 getExtensions() { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/view/ViewGenerator.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/view/ViewGenerator.java index d235d0bac98..14ff5cdfe04 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/view/ViewGenerator.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/view/ViewGenerator.java @@ -115,7 +115,7 @@ public class ViewGenerator { } 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) { for (ExtensionDt next : theSource.getAllUndeclaredExtensions()) { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java index af8c89f3e3d..481fb3eba66 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java @@ -77,6 +77,7 @@ import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.util.UrlUtil; public abstract class BaseParser implements IParser { @@ -937,6 +938,18 @@ public abstract class BaseParser implements IParser { return retVal; } + protected String getExtensionUrl(final String 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 */ diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java index 792bb597db6..8a2363c5935 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java @@ -1442,9 +1442,9 @@ public class JsonParser extends BaseParser implements IJsonLikeParser { getErrorHandler().missingRequiredElement(new ParseLocation(parentElementName), "url"); url = null; } else { - url = jsonElement.getAsString(); + url = getExtensionUrl(jsonElement.getAsString()); } - theState.enteringNewElementExtension(null, url, theIsModifier); + theState.enteringNewElementExtension(null, url, theIsModifier, getServerBaseUrl()); for (String next : nextExtObj.keySet()) { if ("url".equals(next)) { continue; @@ -1795,8 +1795,8 @@ public class JsonParser extends BaseParser implements IJsonLikeParser { public int compareTo(HeldExtension theArg0) { String url1 = myDef != null ? myDef.getExtensionUrl() : myUndeclaredExtension.getUrl(); String url2 = theArg0.myDef != null ? theArg0.myDef.getExtensionUrl() : theArg0.myUndeclaredExtension.getUrl(); - url1 = defaultString(url1); - url2 = defaultString(url2); + url1 = defaultString(getExtensionUrl(url1)); + url2 = defaultString(getExtensionUrl(url2)); return url1.compareTo(url2); } @@ -1808,7 +1808,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser { writeCommentsPreAndPost(myValue, theEventWriter); - JsonParser.write(theEventWriter, "url", myDef.getExtensionUrl()); + JsonParser.write(theEventWriter, "url", getExtensionUrl(myDef.getExtensionUrl())); /* * This makes sure that even if the extension contains a reference to a contained @@ -1834,7 +1834,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser { private void writeUndeclaredExtension(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonLikeWriter theEventWriter, IBaseExtension ext) throws IOException { IBase value = ext.getValue(); - String extensionUrl = ext.getUrl(); + final String extensionUrl = getExtensionUrl(ext.getUrl()); theEventWriter.beginObject(); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java index 02a26311d39..dfaf5ee2fb3 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java @@ -98,8 +98,8 @@ class ParserState { myState.enteringNewElement(theNamespaceUri, theName); } - public void enteringNewElementExtension(StartElement theElem, String theUrlAttr, boolean theIsModifier) { - myState.enteringNewElementExtension(theElem, theUrlAttr, theIsModifier); + public void enteringNewElementExtension(StartElement theElem, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) { + myState.enteringNewElementExtension(theElem, theUrlAttr, theIsModifier, baseServerUrl); } public T getObject() { @@ -795,7 +795,8 @@ class ParserState { /** * Default implementation just handles undeclared extensions */ - public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { + @SuppressWarnings("unused") + public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) { if (myPreResourceState != null && getCurrentElement() instanceof ISupportsUndeclaredExtensions) { ExtensionDt newExtension = new ExtensionDt(theIsModifier); newExtension.setUrl(theUrlAttr); @@ -1489,7 +1490,7 @@ class ParserState { } @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); if (declaredExtension != null) { if (myChildInstance == null) { @@ -1499,7 +1500,7 @@ class ParserState { BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myChildInstance); push(newState); } else { - super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier); + super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier, baseServerUrl); } } @@ -1670,13 +1671,13 @@ class ParserState { } @Override - public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { - RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getDeclaredExtension(theUrlAttr); + public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) { + RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getDeclaredExtension(theUrlAttr, baseServerUrl); if (declaredExtension != null) { BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myInstance); push(newState); } else { - super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier); + super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier, baseServerUrl); } } @@ -2471,7 +2472,7 @@ class ParserState { } @Override - public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { + public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier, final String baseServerUrl) { myDepth++; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java index 516e53cb6cb..81bf5c634fb 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java @@ -208,7 +208,7 @@ public class XmlParser extends BaseParser /*implements IParser */{ } else { url = urlAttr.getValue(); } - parserState.enteringNewElementExtension(elem, url, false); + parserState.enteringNewElementExtension(elem, url, false, getServerBaseUrl()); } else if ("modifierExtension".equals(elem.getName().getLocalPart())) { Attribute urlAttr = elem.getAttributeByName(new QName("url")); String url; @@ -218,7 +218,7 @@ public class XmlParser extends BaseParser /*implements IParser */{ } else { url = urlAttr.getValue(); } - parserState.enteringNewElementExtension(elem, url, true); + parserState.enteringNewElementExtension(elem, url, true, getServerBaseUrl()); } else { String elementName = elem.getName().getLocalPart(); parserState.enteringNewElement(namespaceURI, elementName); @@ -655,11 +655,11 @@ public class XmlParser extends BaseParser /*implements IParser */{ String childName = childNameAndDef.getChildName(); BaseRuntimeElementDefinition childDef = childNameAndDef.getChildDef(); - String extensionUrl = nextChild.getExtensionUrl(); + String extensionUrl = getExtensionUrl(nextChild.getExtensionUrl()); if (nextValue instanceof IBaseExtension && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) { // This is called for the Query resource in DSTU1 only - extensionUrl = ((IBaseExtension) nextValue).getUrl(); + extensionUrl = getExtensionUrl(((IBaseExtension) nextValue).getUrl()); encodeChildElementToStreamWriter(theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theContainedResource, nextChildElem); } else if (extensionUrl != null && childName.equals("extension") == false) { @@ -671,7 +671,7 @@ public class XmlParser extends BaseParser /*implements IParser */{ continue; } } - encodeChildElementToStreamWriter(theResource, theEventWriter, nextValue, childName, childDef, extension.getUrl(), theContainedResource, nextChildElem); + encodeChildElementToStreamWriter(theResource, theEventWriter, nextValue, childName, childDef, getExtensionUrl(extension.getUrl()), theContainedResource, nextChildElem); } else if (nextChild instanceof RuntimeChildNarrativeDefinition && theContainedResource) { // suppress narratives from contained resources } else { @@ -902,7 +902,7 @@ public class XmlParser extends BaseParser /*implements IParser */{ theEventWriter.writeAttribute("id", elementId); } - String url = next.getUrl(); + String url = getExtensionUrl(next.getUrl()); theEventWriter.writeAttribute("url", url); if (next.getValue() != null) { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/BaseClient.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/BaseClient.java index 9def56fb5cd..a0b049b5e95 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/BaseClient.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/BaseClient.java @@ -483,6 +483,7 @@ public abstract class BaseClient implements IRestfulClient { throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader); } IParser parser = respType.newParser(getFhirContext()); + parser.setServerBaseUrl(getUrlBase()); if (myPreferResponseTypes != null) { parser.setPreferTypes(myPreferResponseTypes); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java index 7ab06b5f59e..0675c8a2f90 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java @@ -179,7 +179,7 @@ public class ResourceParameter implements IParameter { } IParser parser = encoding.newParser(ctx); - + parser.setServerBaseUrl(theRequest.getFhirServerBase()); T retVal; try { if (theResourceType != null) { diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java index 9c08053e5b9..5ef901e8871 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java @@ -41,8 +41,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.lang3.StringUtils; -import org.hl7.fhir.dstu3.hapi.rest.server.ServerConformanceProvider; -import org.hl7.fhir.dstu3.model.Conformance; +import org.hl7.fhir.dstu3.hapi.rest.server.ServerCapabilityStatementProvider; +import ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider; +import org.hl7.fhir.dstu3.model.CapabilityStatement; +import ca.uhn.fhir.model.dstu2.resource.Conformance; import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.LoggerFactory; @@ -83,8 +85,8 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv private RestulfulServerConfiguration serverConfiguration = new RestulfulServerConfiguration(); /** the conformance. It is created once during startup */ - private Conformance myDstu3Conformance; - private ca.uhn.fhir.model.dstu2.resource.Conformance myDstu2Conformance; + private CapabilityStatement myDstu3Conformance; + private Conformance myDstu2Conformance; /** * Constructor allowing the description, servername and server to be set @@ -142,11 +144,12 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv hardcodedServerAddressStrategy.setValue(getBaseForServer()); serverConfiguration.setServerAddressStrategy(hardcodedServerAddressStrategy); if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { - ServerConformanceProvider serverConformanceProvider = new ServerConformanceProvider(serverConfiguration); + // ServerConformanceProvider serverConformanceProvider = new ServerConformanceProvider(serverConfiguration); + final ServerCapabilityStatementProvider serverConformanceProvider = new ServerCapabilityStatementProvider((serverConfiguration)); serverConformanceProvider.initializeOperations(); myDstu3Conformance = serverConformanceProvider.getServerConformance(null); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) { - ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider serverConformanceProvider = new ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider(serverConfiguration); + ServerConformanceProvider serverConformanceProvider = new ServerConformanceProvider(serverConfiguration); serverConformanceProvider.initializeOperations(); myDstu2Conformance = serverConformanceProvider.getServerConformance(null); } @@ -275,9 +278,9 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv @Override public Class getResourceType() { if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { - return Class.class.cast(Conformance.class); + return Class.class.cast(CapabilityStatement.class); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) { - return Class.class.cast(ca.uhn.fhir.model.dstu2.resource.Conformance.class); + return Class.class.cast(Conformance.class); } return null; } diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java index 63e149a138c..a8ce9690975 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java @@ -32,6 +32,7 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; @@ -125,7 +126,8 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults { * @return the ascii string for the server base */ public String getBaseForServer() { - return getUriInfo().getBaseUri().toASCIIString(); + final String url = getUriInfo().getBaseUri().toASCIIString(); + return StringUtils.isNotBlank(url) && url.endsWith("/") ? url.substring(0, url.length() - 1) : url; } /** diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java index 071d0fd0885..843f1a93ace 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java @@ -286,6 +286,12 @@ implements IRestfulServer, IResourceProvider { return execute(theRequest, compartment); } + @POST + @Path("/$validate") + public Response validate(final String resource) throws IOException { + return customOperation(resource, RequestTypeEnum.POST, null, "$validate", RestOperationTypeEnum.EXTENDED_OPERATION_TYPE); + } + /** * Execute the method described by the requestBuilder and methodKey * diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java index efb8508273c..ebdfbbe1b61 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java @@ -1,7 +1,9 @@ package ca.uhn.fhir.jaxrs.server; import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -24,10 +26,11 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; -import org.hl7.fhir.dstu3.model.Conformance; +import org.hl7.fhir.dstu3.model.CapabilityStatement; import org.hl7.fhir.dstu3.model.DateType; import org.hl7.fhir.dstu3.model.IdType; import org.hl7.fhir.dstu3.model.Identifier; +import org.hl7.fhir.dstu3.model.OperationOutcome; import org.hl7.fhir.dstu3.model.Parameters; import org.hl7.fhir.dstu3.model.Patient; import org.hl7.fhir.dstu3.model.Resource; @@ -154,7 +157,7 @@ public class AbstractJaxRsResourceProviderDstu3Test { toCreate.getIdentifier().add(new Identifier().setValue("myIdentifier")); outcome.setResource(toCreate); - when(mock.create(patientCaptor.capture(), eq("Patient?_format=json&identifier=2"))).thenReturn(outcome); + when(mock.create(patientCaptor.capture(), eq("/Patient?_format=json&identifier=2"))).thenReturn(outcome); client.setEncoding(EncodingEnum.JSON); MethodOutcome response = client.create().resource(toCreate).conditional() @@ -168,7 +171,7 @@ public class AbstractJaxRsResourceProviderDstu3Test { /** Conformance - Server */ @Test public void testConformance() { - final Conformance conf = client.fetchConformance().ofType(Conformance.class).execute(); + final CapabilityStatement conf = client.fetchConformance().ofType(CapabilityStatement.class).execute(); assertEquals(conf.getRest().get(0).getResource().get(0).getType().toString(), "Patient"); } @@ -426,6 +429,21 @@ public class AbstractJaxRsResourceProviderDstu3Test { assertTrue(e.getMessage().contains("999955541264")); } } + + @Test + public void testValidate() { + // prepare mock + final OperationOutcome oo = new OperationOutcome(); + final Patient patient = new Patient(); + patient.addIdentifier((new Identifier().setValue("1"))); + //invoke + final Parameters inParams = new Parameters(); + inParams.addParameter().setResource(patient); + + final MethodOutcome mO = client.validate().resource(patient).execute(); + //verify + assertNotNull(mO.getOperationOutcome()); + } @BeforeClass public static void setUpClass() throws Exception { diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java index 837f2509963..7bd8fdf928d 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java @@ -1,6 +1,7 @@ package ca.uhn.fhir.jaxrs.server; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -44,9 +45,11 @@ import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProvider; import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; +import ca.uhn.fhir.model.dstu2.composite.IdentifierDt; import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry; import ca.uhn.fhir.model.dstu2.resource.Conformance; +import ca.uhn.fhir.model.dstu2.resource.OperationOutcome; import ca.uhn.fhir.model.dstu2.resource.Parameters; import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.model.primitive.BoundCodeDt; @@ -152,7 +155,7 @@ public class AbstractJaxRsResourceProviderTest { toCreate.getIdentifierFirstRep().setValue("myIdentifier"); outcome.setResource(toCreate); - when(mock.create(patientCaptor.capture(), eq("Patient?_format=json&identifier=2"))).thenReturn(outcome); + when(mock.create(patientCaptor.capture(), eq("/Patient?_format=json&identifier=2"))).thenReturn(outcome); client.setEncoding(EncodingEnum.JSON); MethodOutcome response = client.create().resource(toCreate).conditional() @@ -411,6 +414,21 @@ public class AbstractJaxRsResourceProviderTest { } } + @Test + public void testValidate() { + // prepare mock + final OperationOutcome oo = new OperationOutcome(); + final Patient patient = new Patient(); + patient.addIdentifier((new IdentifierDt().setValue("1"))); + //invoke + final Parameters inParams = new Parameters(); + inParams.addParameter().setResource(patient); + + final MethodOutcome mO = client.validate().resource(patient).execute(); + //verify + assertNotNull(mO.getOperationOutcome()); + } + private T withId(final T id) { return argThat(new BaseMatcher() { @Override diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProvider.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProvider.java index 8181857cf1b..aae7f63c4df 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProvider.java @@ -17,6 +17,7 @@ import org.mockito.Mockito; import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider; import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor; import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.dstu2.resource.OperationOutcome; import ca.uhn.fhir.model.dstu2.resource.Parameters; import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.model.primitive.IdDt; @@ -32,6 +33,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam; import ca.uhn.fhir.rest.annotation.ResourceParam; import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Update; +import ca.uhn.fhir.rest.annotation.Validate; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; @@ -125,6 +127,13 @@ public class TestJaxRsMockPatientRestProvider extends AbstractJaxRsResourceProvi public Parameters someCustomOperation(@IdParam IdDt myId, @OperationParam(name = "dummy") StringDt dummyInput) { return mock.someCustomOperation(myId, dummyInput); } + + @Validate() + public MethodOutcome validate(@ResourceParam final Patient resource) { + final MethodOutcome mO = new MethodOutcome(); + mO.setOperationOutcome(new OperationOutcome()); + return mO; + } @Override public Class getResourceType() { diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu3.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu3.java index c36a5a1d6bf..6ebfa89393c 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu3.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu3.java @@ -13,6 +13,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.hl7.fhir.dstu3.model.IdType; +import org.hl7.fhir.dstu3.model.OperationOutcome; import org.hl7.fhir.dstu3.model.Parameters; import org.hl7.fhir.dstu3.model.Patient; import org.hl7.fhir.dstu3.model.StringType; @@ -34,6 +35,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam; import ca.uhn.fhir.rest.annotation.ResourceParam; import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Update; +import ca.uhn.fhir.rest.annotation.Validate; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; @@ -128,6 +130,13 @@ public class TestJaxRsMockPatientRestProviderDstu3 extends AbstractJaxRsResource return mock.someCustomOperation(myId, dummyInput); } + @Validate() + public MethodOutcome validate(@ResourceParam final Patient resource) { + MethodOutcome mO = new MethodOutcome(); + mO.setOperationOutcome(new OperationOutcome()); + return mO; + } + @Override public Class getResourceType() { return Patient.class; diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerDstu1Test.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerDstu1Test.java index c74ebbc0c9c..c9e3da34244 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerDstu1Test.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerDstu1Test.java @@ -56,17 +56,17 @@ public class ModelScannerDstu1Test { assertEquals(RuntimeChildCompositeDatatypeDefinition.class, def.getChildByNameOrThrowDataFormatException("identifier").getClass()); - RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1"); + RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1", ""); assertNotNull(ext); BaseRuntimeElementDefinition valueString = ext.getChildByName("valueString"); assertNotNull(valueString); - ext = def.getDeclaredExtension("http://foo/#f2"); + ext = def.getDeclaredExtension("http://foo/#f2", ""); assertNotNull(ext); valueString = ext.getChildByName("valueString"); assertNotNull(valueString); - ext = def.getDeclaredExtension("http://bar/#b1"); + ext = def.getDeclaredExtension("http://bar/#b1", ""); assertNotNull(ext); RuntimeChildDeclaredExtensionDefinition childExt = ext.getChildExtensionForUrl("http://bar/#b1/1"); assertNotNull(childExt); diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java index 00968104c63..9e3d081e806 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java @@ -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 public static void beforeClass() { ourCtx = FhirContext.forDstu1(); diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java new file mode 100644 index 00000000000..cfb5f30e234 --- /dev/null +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java @@ -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; + } + +} diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java index 12d87c133b6..5a9b3e1df20 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java @@ -1997,6 +1997,69 @@ public class XmlParserTest { assertEquals(15, bundleR.getTotalResults().getValue().intValue()); } + @Test + public void testCustomUrlExtension() { + final String expected = ""; + + 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 = "<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 public static void beforeClass() { XMLUnit.setIgnoreAttributeOrder(true); diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/CustomPatientDstu2.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/CustomPatientDstu2.java new file mode 100644 index 00000000000..58b2f163d3d --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/CustomPatientDstu2.java @@ -0,0 +1,29 @@ +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.BooleanDt; + +@ResourceDef(name = "Patient", profile = "Patient") +public class CustomPatientDstu2 extends Patient { + + + private static final long serialVersionUID = 1L; + + @Child(name = "homeless", order = 1) + @Extension(url = "/StructureDefinition/homeless", definedLocally = true, isModifier = false) + @Description(shortDefinition = "The patient being homeless, true if homeless") + private BooleanDt homeless; + + + public BooleanDt getHomeless() { + return homeless; + } + + public void setHomeless(final BooleanDt homeless) { + this.homeless = homeless; + } +} \ No newline at end of file diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java index fb40a115c44..b109314a0b3 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2Test.java @@ -9,12 +9,14 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.io.IOException; +import java.io.StringReader; import java.util.*; import org.apache.commons.io.IOUtils; @@ -48,6 +50,7 @@ import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum; import ca.uhn.fhir.model.dstu2.valueset.MaritalStatusCodesEnum; import ca.uhn.fhir.model.dstu2.valueset.ObservationStatusEnum; import ca.uhn.fhir.model.dstu2.valueset.UnknownContentCodeEnum; +import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.model.primitive.CodeDt; import ca.uhn.fhir.model.primitive.DateDt; import ca.uhn.fhir.model.primitive.DateTimeDt; @@ -1914,5 +1917,87 @@ public class JsonParserDstu2Test { assertEquals("2011-01-01", condition.getDateRecordedElement().getValueAsString()); } - + + /** + * Test for the url generated based on the server config + */ + @Test + public void testGeneratedUrls() { + final IParser jsonParser = ourCtx.newJsonParser().setPrettyPrint(true); + jsonParser.setServerBaseUrl("http://myserver.com"); + + final CustomPatientDstu2 patient = new CustomPatientDstu2(); + patient.setHomeless(new BooleanDt(true)); + + final String parsedPatient = jsonParser.encodeResourceToString(patient); + + assertTrue(parsedPatient.contains("http://myserver.com/StructureDefinition/Patient")); + 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()); + + } } diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java new file mode 100644 index 00000000000..4b62f4ea575 --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java @@ -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(); + } + +} diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java index 84dbb4652b2..1b3e9617515 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java @@ -2728,6 +2728,89 @@ public class XmlParserDstu2Test { assertEquals("Patient", reincarnatedPatient.getId().getResourceType()); } + /** + * Test for the url generated based on the server config + */ + @Test + public void testGeneratedUrls() { + final IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true); + xmlParser.setServerBaseUrl("http://myserver.com"); + + final CustomPatientDstu2 patient = new CustomPatientDstu2(); + patient.setHomeless(new BooleanDt(true)); + + final String parsedPatient = xmlParser.encodeResourceToString(patient); + + assertTrue(parsedPatient.contains("<profile value=\"http://myserver.com/StructureDefinition/Patient\"/>")); + 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 public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/elementmodel/Property.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/elementmodel/Property.java index 0c5a2510b81..62ade417214 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/elementmodel/Property.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/elementmodel/Property.java @@ -3,6 +3,7 @@ package org.hl7.fhir.dstu3.elementmodel; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.dstu3.conformance.ProfileUtilities; import org.hl7.fhir.dstu3.context.IWorkerContext; import org.hl7.fhir.dstu3.formats.FormatUtilities; @@ -240,7 +241,13 @@ public class Property { } } if (!"xhtml".equals(t)) { - sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+t); + final String url; + if (StringUtils.isNotBlank(ed.getType().get(0).getProfile())) { + url = ed.getType().get(0).getProfile(); + } else { + url = "http://hl7.org/fhir/StructureDefinition/" + t; + } + sd = context.fetchResource(StructureDefinition.class, url); if (sd == null) throw new DefinitionException("Unable to find class '"+t+"' for name '"+elementName+"' on property "+definition.getPath()); children = ProfileUtilities.getChildMap(sd, sd.getSnapshot().getElement().get(0)); diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/ModelScannerDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/ModelScannerDstu3Test.java index d699828d2a8..edb42d95db3 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/ModelScannerDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/ModelScannerDstu3Test.java @@ -81,17 +81,17 @@ public class ModelScannerDstu3Test { assertEquals(RuntimeChildCompositeDatatypeDefinition.class, def.getChildByNameOrThrowDataFormatException("identifier").getClass()); - RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1"); + RuntimeChildDeclaredExtensionDefinition ext = def.getDeclaredExtension("http://foo/#f1", ""); assertNotNull(ext); BaseRuntimeElementDefinition<?> valueString = ext.getChildByName("valueString"); assertNotNull(valueString); - ext = def.getDeclaredExtension("http://foo/#f2"); + ext = def.getDeclaredExtension("http://foo/#f2", ""); assertNotNull(ext); valueString = ext.getChildByName("valueString"); assertNotNull(valueString); - ext = def.getDeclaredExtension("http://bar/#b1"); + ext = def.getDeclaredExtension("http://bar/#b1", ""); assertNotNull(ext); RuntimeChildDeclaredExtensionDefinition childExt = ext.getChildExtensionForUrl("http://bar/#b1/1"); assertNotNull(childExt); diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/CustomPatientDstu3.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/CustomPatientDstu3.java new file mode 100644 index 00000000000..53074d730f9 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/CustomPatientDstu3.java @@ -0,0 +1,29 @@ +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.BooleanType; +import org.hl7.fhir.dstu3.model.Patient; + +@ResourceDef(name = "Patient", profile = "Patient") +public class CustomPatientDstu3 extends Patient { + + + private static final long serialVersionUID = 1L; + + @Child(name = "homeless", order = 1) + @Extension(url = "/StructureDefinition/homeless", definedLocally = true, isModifier = false) + @Description(shortDefinition = "The patient being homeless, true if homeless") + private BooleanType homeless; + + + public BooleanType getHomeless() { + return homeless; + } + + public void setHomeless(final BooleanType homeless) { + this.homeless = homeless; + } +} \ No newline at end of file diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java index 662c25e92a7..d2b46acbc44 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.io.IOException; +import java.io.StringReader; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -2169,6 +2170,72 @@ public class JsonParserDstu3Test { 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 public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java new file mode 100644 index 00000000000..d668ecf7e08 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/MyPatientWithCustomUrlExtension.java @@ -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(); + } + +} diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java index 35db996195d..4fc802472ec 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java @@ -3187,6 +3187,89 @@ public class XmlParserDstu3Test { } + /** + * Test for the url generated based on the server config + */ + @Test + public void testGeneratedUrls() { + final IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true); + xmlParser.setServerBaseUrl("http://myserver.com"); + + final CustomPatientDstu3 patient = new CustomPatientDstu3(); + patient.setHomeless(new BooleanType(true)); + + final String parsedPatient = xmlParser.encodeResourceToString(patient); + + assertTrue(parsedPatient.contains("<profile value=\"http://myserver.com/StructureDefinition/Patient\"/>")); + 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 public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/validation/InstanceValidator.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/validation/InstanceValidator.java index 53d6af47775..c631e46c8ba 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/validation/InstanceValidator.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/validation/InstanceValidator.java @@ -999,8 +999,15 @@ public InstanceValidator(IWorkerContext theContext) throws Exception { return null; } - private StructureDefinition getProfileForType(String type) throws Exception { - return context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + type); + private StructureDefinition getProfileForType(ElementDefinition ed, String type) throws Exception { + //return context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + type); + final String url; + if (!"Reference".equals(type) && ed.getType().get(0).hasProfile()) { + url = ed.getType().get(0).getProfile().get(0).getValue(); + } else { + url = "http://hl7.org/fhir/StructureDefinition/" + type; + } + return context.fetchResource(StructureDefinition.class, url); } private Element getValueForDiscriminator(WrapperElement element, String discriminator, ElementDefinition criteria) { @@ -1188,8 +1195,14 @@ public InstanceValidator(IWorkerContext theContext) throws Exception { return context.fetchResource(StructureDefinition.class, pr); } - private ElementDefinition resolveType(String type) throws EOperationOutcome, Exception { - String url = "http://hl7.org/fhir/StructureDefinition/" + type; + private ElementDefinition resolveType(ElementDefinition ed, String type) throws EOperationOutcome, Exception { + final String url; + if (ed.getType().get(0).hasProfile()) { + url = ed.getType().get(0).getProfile().get(0).getValue(); + } else { + url = "http://hl7.org/fhir/StructureDefinition/" + type; + } + StructureDefinition sd = context.fetchResource(StructureDefinition.class, url); if (sd == null || !sd.hasSnapshot()) return null; @@ -1809,7 +1822,7 @@ public InstanceValidator(IWorkerContext theContext) throws Exception { type = null; } } - NodeStack localStack = stack.push(ei.element, ei.count, ei.definition, type == null ? typeDefn : resolveType(type)); + NodeStack localStack = stack.push(ei.element, ei.count, ei.definition, type == null ? typeDefn : resolveType(ei.definition, type)); String localStackLiterapPath = localStack.getLiteralPath(); String eiPath = ei.path; assert(eiPath.equals(localStackLiterapPath)) : "ei.path: " + ei.path + " - localStack.getLiterapPath: " + localStackLiterapPath; @@ -1834,7 +1847,7 @@ public InstanceValidator(IWorkerContext theContext) throws Exception { validateContains(errors, ei.path, ei.definition, definition, ei.element, localStack, !isBundleEntry(ei.path) && !isParametersEntry(ei.path) && shouldCheckForIdPresence); // if // (str.matches(".*([.,/])work\\1$")) else { - StructureDefinition p = getProfileForType(type); + StructureDefinition p = getProfileForType(ei.definition, type); if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.path, p != null, "Unknown type " + type)) { validateElement(errors, p, p.getSnapshot().getElement().get(0), profile, ei.definition, ei.element, type, localStack); }