diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java index b3be50e8437..42e4e67d491 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java @@ -7,6 +7,7 @@ import java.io.InputStreamReader; import java.util.*; import org.apache.commons.io.Charsets; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; @@ -22,6 +23,10 @@ import ca.uhn.fhir.context.FhirContext; public class DefaultProfileValidationSupport implements IValidationSupport { + private static final String URL_PREFIX_VALUE_SET = "http://hl7.org/fhir/ValueSet/"; + private static final String URL_PREFIX_STRUCTURE_DEFINITION = "http://hl7.org/fhir/StructureDefinition/"; + private static final String URL_PREFIX_STRUCTURE_DEFINITION_BASE = "http://hl7.org/fhir/"; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DefaultProfileValidationSupport.class); private Map myCodeSystems; @@ -86,51 +91,28 @@ public class DefaultProfileValidationSupport implements IValidationSupport { public T fetchResource(FhirContext theContext, Class theClass, String theUri) { Validate.notBlank(theUri, "theUri must not be null or blank"); - if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) { + if (theClass.equals(StructureDefinition.class)) { return (T) fetchStructureDefinition(theContext, theUri); } - if (theUri.startsWith("http://hl7.org/fhir/ValueSet/")) { + + if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) { return (T) fetchValueSet(theContext, theUri); } - // if (theUri.startsWith("http://hl7.org/fhir/ValueSet/")) { - // Map defaultValueSets = myDefaultValueSets; - // if (defaultValueSets == null) { - // String path = theContext.getVersion().getPathToSchemaDefinitions().replace("/schema", "/valueset") + "/valuesets.xml"; - // InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(path); - // if (valuesetText == null) { - // return null; - // } - // InputStreamReader reader; - // try { - // reader = new InputStreamReader(valuesetText, "UTF-8"); - // } catch (UnsupportedEncodingException e) { - // // Shouldn't happen! - // throw new InternalErrorException("UTF-8 encoding not supported on this platform", e); - // } - // - // defaultValueSets = new HashMap(); - // - // Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader); - // for (BundleEntryComponent next : bundle.getEntry()) { - // IdType nextId = new IdType(next.getFullUrl()); - // if (nextId.isEmpty() || !nextId.getValue().startsWith("http://hl7.org/fhir/ValueSet/")) { - // continue; - // } - // defaultValueSets.put(nextId.toVersionless().getValue(), (ValueSet) next.getResource()); - // } - // - // myDefaultValueSets = defaultValueSets; - // } - // - // return (T) defaultValueSets.get(theUri); - // } return null; } @Override public StructureDefinition fetchStructureDefinition(FhirContext theContext, String theUrl) { - return provideStructureDefinitionMap(theContext).get(theUrl); + String url = theUrl; + if (url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) { + // no change + } else if (url.indexOf('/') == -1) { + url = URL_PREFIX_STRUCTURE_DEFINITION + url; + } else if (StringUtils.countMatches(url, '/') == 1) { + url = URL_PREFIX_STRUCTURE_DEFINITION_BASE + url; + } + return provideStructureDefinitionMap(theContext).get(url); } ValueSet fetchValueSet(FhirContext theContext, String theSystem) { diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java index cb4b307ba59..08820d6c862 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java @@ -1,14 +1,14 @@ package org.hl7.fhir.dstu3.hapi.validation; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.Validate; -import org.hl7.fhir.dstu3.model.CodeSystem; -import org.hl7.fhir.dstu3.model.StructureDefinition; -import org.hl7.fhir.dstu3.model.ValueSet; +import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -21,112 +21,154 @@ import ca.uhn.fhir.context.FhirContext; */ public class PrePopulatedValidationSupport implements IValidationSupport { - private Map myStructureDefinitions; - private Map myValueSets; - private Map myCodeSystems; + private Map myCodeSystems; + private Map myStructureDefinitions; + private Map myValueSets; - /** - * Constructor - */ - public PrePopulatedValidationSupport() { - myStructureDefinitions = new HashMap(); - myValueSets = new HashMap(); - myCodeSystems = new HashMap(); - } - - - /** - * Add a new StructureDefinition resource which will be available to the validator. Note that - * {@link StructureDefinition#getUrl() the URL field) in this resource must contain a value as this - * value will be used as the logical URL. - */ - public void addStructureDefinition(StructureDefinition theStructureDefinition) { - Validate.notBlank(theStructureDefinition.getUrl(), "theStructureDefinition.getUrl() must not return a value"); - myStructureDefinitions.put(theStructureDefinition.getUrl(), theStructureDefinition); - } - - /** - * Add a new ValueSet resource which will be available to the validator. Note that - * {@link ValueSet#getUrl() the URL field) in this resource must contain a value as this - * value will be used as the logical URL. - */ - public void addValueSet(ValueSet theValueSet) { - Validate.notBlank(theValueSet.getUrl(), "theValueSet.getUrl() must not return a value"); - myValueSets.put(theValueSet.getUrl(), theValueSet); - } + /** + * Constructor + */ + public PrePopulatedValidationSupport() { + myStructureDefinitions = new HashMap(); + myValueSets = new HashMap(); + myCodeSystems = new HashMap(); + } - /** - * Add a new CodeSystem resource which will be available to the validator. Note that - * {@link CodeSystem#getUrl() the URL field) in this resource must contain a value as this - * value will be used as the logical URL. - */ - public void addCodeSystem(CodeSystem theCodeSystem) { - Validate.notBlank(theCodeSystem.getUrl(), "theCodeSystem.getUrl() must not return a value"); - myCodeSystems.put(theCodeSystem.getUrl(), theCodeSystem); - } + /** + * Constructor + * + * @param theStructureDefinitions + * The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and + * values are the resource itself. + * @param theValueSets + * The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are + * the resource itself. + * @param theCodeSystems + * The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are + * the resource itself. + */ + public PrePopulatedValidationSupport(Map theStructureDefinitions, Map theValueSets, Map theCodeSystems) { + myStructureDefinitions = theStructureDefinitions; + myValueSets = theValueSets; + myCodeSystems = theCodeSystems; + } - /** - * Constructor - * - * @param theStructureDefinitions - * The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and - * values are the resource itself. - * @param theValueSets - * The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are - * the resource itself. - * @param theCodeSystems - * The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are - * the resource itself. - */ - public PrePopulatedValidationSupport(Map theStructureDefinitions, Map theValueSets, Map theCodeSystems) { - myStructureDefinitions = theStructureDefinitions; - myValueSets = theValueSets; - myCodeSystems = theCodeSystems; - } + /** + * Add a new CodeSystem resource which will be available to the validator. Note that + * {@link CodeSystem#getUrl() the URL field) in this resource must contain a value as this + * value will be used as the logical URL. + *

+ * Note that if the URL is a canonical FHIR URL (e.g. http://hl7.org/StructureDefinition/Extension), + * it will be stored in three ways: + *

    + *
  • Extension
  • + *
  • StructureDefinition/Extension
  • + *
  • http://hl7.org/StructureDefinition/Extension
  • + *
+ *

+ */ + public void addCodeSystem(CodeSystem theCodeSystem) { + Validate.notBlank(theCodeSystem.getUrl(), "theCodeSystem.getUrl() must not return a value"); + addToMap(theCodeSystem, myCodeSystems, theCodeSystem.getUrl()); + } - @Override - public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) { - return null; - } + /** + * Add a new StructureDefinition resource which will be available to the validator. Note that + * {@link StructureDefinition#getUrl() the URL field) in this resource must contain a value as this + * value will be used as the logical URL. + *

+ * Note that if the URL is a canonical FHIR URL (e.g. http://hl7.org/StructureDefinition/Extension), + * it will be stored in three ways: + *

    + *
  • Extension
  • + *
  • StructureDefinition/Extension
  • + *
  • http://hl7.org/StructureDefinition/Extension
  • + *
+ *

+ */ + public void addStructureDefinition(StructureDefinition theStructureDefinition) { + Validate.notBlank(theStructureDefinition.getUrl(), "theStructureDefinition.getUrl() must not return a value"); + addToMap(theStructureDefinition, myStructureDefinitions, theStructureDefinition.getUrl()); + } - @Override - public List fetchAllStructureDefinitions(FhirContext theContext) { - return new ArrayList(myStructureDefinitions.values()); - } + private void addToMap(T theStructureDefinition, Map map, String theUrl) { + if (isNotBlank(theUrl)) { + map.put(theUrl, theStructureDefinition); - @Override - public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) { - return myCodeSystems.get(theSystem); - } + int lastSlashIdx = theUrl.lastIndexOf('/'); + if (lastSlashIdx != -1) { + map.put(theUrl.substring(lastSlashIdx + 1), theStructureDefinition); + int previousSlashIdx = theUrl.lastIndexOf('/', lastSlashIdx - 1); + if (previousSlashIdx != -1) { + map.put(theUrl.substring(previousSlashIdx + 1), theStructureDefinition); + } + } - @SuppressWarnings("unchecked") - @Override - public T fetchResource(FhirContext theContext, Class theClass, String theUri) { - if (theClass.equals(StructureDefinition.class)) { - return (T) myStructureDefinitions.get(theUri); - } - if (theClass.equals(ValueSet.class)) { - return (T) myValueSets.get(theUri); - } - if (theClass.equals(CodeSystem.class)) { - return (T) myCodeSystems.get(theUri); - } - return null; - } + } + } - @Override - public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) { - return myStructureDefinitions.get(theUrl); - } + /** + * Add a new ValueSet resource which will be available to the validator. Note that + * {@link ValueSet#getUrl() the URL field) in this resource must contain a value as this + * value will be used as the logical URL. + *

+ * Note that if the URL is a canonical FHIR URL (e.g. http://hl7.org/StructureDefinition/Extension), + * it will be stored in three ways: + *

    + *
  • Extension
  • + *
  • StructureDefinition/Extension
  • + *
  • http://hl7.org/StructureDefinition/Extension
  • + *
+ *

+ */ + public void addValueSet(ValueSet theValueSet) { + Validate.notBlank(theValueSet.getUrl(), "theValueSet.getUrl() must not return a value"); + addToMap(theValueSet, myValueSets, theValueSet.getUrl()); + } - @Override - public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) { - return false; - } + @Override + public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) { + return null; + } - @Override - public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) { - return null; - } + @Override + public List fetchAllStructureDefinitions(FhirContext theContext) { + return new ArrayList(myStructureDefinitions.values()); + } + + @Override + public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) { + return myCodeSystems.get(theSystem); + } + + @SuppressWarnings("unchecked") + @Override + public T fetchResource(FhirContext theContext, Class theClass, String theUri) { + if (theClass.equals(StructureDefinition.class)) { + return (T) myStructureDefinitions.get(theUri); + } + if (theClass.equals(ValueSet.class)) { + return (T) myValueSets.get(theUri); + } + if (theClass.equals(CodeSystem.class)) { + return (T) myCodeSystems.get(theUri); + } + return null; + } + + @Override + public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) { + return myStructureDefinitions.get(theUrl); + } + + @Override + public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) { + return false; + } + + @Override + public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) { + return null; + } } \ No newline at end of file diff --git a/hapi-fhir-structures-dstu3/src/test/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupportTest.java b/hapi-fhir-structures-dstu3/src/test/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupportTest.java new file mode 100644 index 00000000000..c37a58ed87c --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupportTest.java @@ -0,0 +1,34 @@ +package org.hl7.fhir.dstu3.hapi.validation; + +import static org.junit.Assert.*; + +import org.junit.AfterClass; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.util.TestUtil; + +public class DefaultProfileValidationSupportTest { + + private DefaultProfileValidationSupport mySvc = new DefaultProfileValidationSupport(); + private static FhirContext ourCtx = FhirContext.forDstu3(); + + @Test + public void testGetStructureDefinitionsWithRelativeUrls() { + assertNotNull(mySvc.fetchStructureDefinition(ourCtx, "http://hl7.org/fhir/StructureDefinition/Extension")); + assertNotNull(mySvc.fetchStructureDefinition(ourCtx, "StructureDefinition/Extension")); + assertNotNull(mySvc.fetchStructureDefinition(ourCtx, "Extension")); + + assertNull(mySvc.fetchStructureDefinition(ourCtx, "http://hl7.org/fhir/StructureDefinition/Extension2")); + assertNull(mySvc.fetchStructureDefinition(ourCtx, "StructureDefinition/Extension2")); + assertNull(mySvc.fetchStructureDefinition(ourCtx, "Extension2")); + + } + + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + +} diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/validation/StructureMapTests2.java b/hapi-fhir-structures-dstu3/src/test/java/org/hl7/fhir/dstu3/hapi/validation/StructureMapTest.java similarity index 95% rename from hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/validation/StructureMapTests2.java rename to hapi-fhir-structures-dstu3/src/test/java/org/hl7/fhir/dstu3/hapi/validation/StructureMapTest.java index 023076d3e02..f2a6c9cedf2 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/validation/StructureMapTests2.java +++ b/hapi-fhir-structures-dstu3/src/test/java/org/hl7/fhir/dstu3/hapi/validation/StructureMapTest.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.dstu3.validation; +package org.hl7.fhir.dstu3.hapi.validation; import static org.junit.Assert.assertEquals; @@ -7,24 +7,19 @@ import java.util.*; import javax.annotation.Nullable; import org.hl7.fhir.dstu3.context.IWorkerContext; -import org.hl7.fhir.dstu3.hapi.validation.*; import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.utils.StructureMapUtilities; -import org.junit.*; +import org.junit.Before; +import org.junit.Test; import ca.uhn.fhir.context.FhirContext; -public class StructureMapTests2 { - - /** - * path to the files used to test the profile generator. - */ - String resourcePath = null; +public class StructureMapTest { /** * The logger object. */ - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StructureMapTests2.class); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StructureMapTest.class); /** * The basic fhir context used to parse structure definitions. @@ -36,141 +31,60 @@ public class StructureMapTests2 { */ IWorkerContext hapiContext; + /** + * path to the files used to test the profile generator. + */ + String resourcePath = null; + /** * Used to validate definitions as well as add new structure definitions to a registry. */ PrePopulatedValidationSupport validationSupport; - /** - * Sets up the resource paths as well as create the contexts using a defalut validator to start with. - * - * @throws Exception - */ - @Before - public void setUp() throws Exception { - // resourcePath = getFileFromURL().getParent(); - if (this.context == null) - this.context = FhirContext.forDstu3(); + public StructureMap.StructureMapGroupRuleSourceComponent buildSource(String context, @Nullable String element, @Nullable String variable, @Nullable String type, @Nullable Integer min, + @Nullable String max) { + StructureMap.StructureMapGroupRuleSourceComponent retVal = new StructureMap.StructureMapGroupRuleSourceComponent(); + retVal.setContext(context); + if (element != null) + retVal.setElement(element); + if (variable != null) + retVal.setVariable(variable); + if (type != null) + retVal.setType(type); + if (min != null) + retVal.setMin(min); + if (max != null) + retVal.setMax(max); + return retVal; } - /** - * See #682 - */ - @Test - @Ignore - public void testMappingTransform() throws Exception { - Map maps = new HashMap(); // Instantiate a hashmap for StructureMaps - this.validationSupport = new PrePopulatedValidationSupport(); // Create Validation Instance - for (StructureDefinition sd : new DefaultProfileValidationSupport().fetchAllStructureDefinitions(this.context)) { // Read in the default Structure Definitions into a validator that allows custom - // declared structure definitions. - this.validationSupport.addStructureDefinition(sd); + public List buildSourceList(StructureMap.StructureMapGroupRuleSourceComponent[] sources) { + List retVal = new ArrayList(); + retVal.addAll(Arrays.asList(sources)); + return retVal; + } + + public StructureMap.StructureMapGroupRuleTargetComponent buildTarget(@Nullable String context, @Nullable String element, @Nullable String variable, + @Nullable StructureMap.StructureMapTransform transform, @Nullable TargetParam[] params) throws Exception { + StructureMap.StructureMapGroupRuleTargetComponent retVal = new StructureMap.StructureMapGroupRuleTargetComponent(); + if (context != null) + retVal.setContext(context); + if (element != null) + retVal.setElement(element); + if (variable != null) + retVal.setVariable(variable); + if (transform != null) + retVal.setTransform(transform); + if (params != null) { + if (params.length > 0) + retVal.setParameter(this.constructParameters(params)); } - StructureDefinition sd1 = this.createTestStructure(); // Calls a method that constructs a comp - this.validationSupport.addStructureDefinition(sd1); // Add custom structure to validation support. - this.hapiContext = new HapiWorkerContext(this.context, this.validationSupport);// Init the Hapi Work - StructureMap map = this.createTestStructuremap(); - maps.put(map.getUrl(), map); - StructureMapUtilities scu = new StructureMapUtilities(hapiContext, maps, null, null); - List result = scu.analyse(null, map).getProfiles(); - - assertEquals(1, result.size()); - - ourLog.info(context.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.get(0))); - } - - public StructureDefinition createTestStructure() { - StructureDefinition sd = new StructureDefinition(); - sd.setId("TestStructure"); - sd.setUrl("http://opencimi.org/structuredefinition/TestStructure"); - sd.setStatus(Enumerations.PublicationStatus.DRAFT); - sd.setName("TestStructure"); - sd.setType("TestStructure"); - sd.setSnapshot(this.createTestSnapshot()); - sd.setDifferential(this.createTestDiff()); - sd.setKind(StructureDefinition.StructureDefinitionKind.LOGICAL); - - return sd; - } - - public StructureDefinition.StructureDefinitionSnapshotComponent createTestSnapshot() { - StructureDefinition.StructureDefinitionSnapshotComponent retVal = new StructureDefinition.StructureDefinitionSnapshotComponent(); - List eList = new ArrayList(); - ElementDefinition ed0 = new ElementDefinition(); - // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); - // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); - ed0.setId("TestStructure"); - ed0.setSliceName("TestStructure"); - ed0.setPath("TestStructure"); - // ed0.setBase(base); - ed0.setMin(1); - ed0.setMax("1"); - eList.add(ed0); - - ElementDefinition ed = new ElementDefinition(); - // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); - // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); - ed.setId("system"); - ed.setSliceName("system"); - ed.setPath("TestStructure.system"); - // ed.setBase(base); - ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging")); - // ed.setType(this.createTypeRefList()); - ed.setMin(1); - ed.setMax("1"); - eList.add(ed); - retVal.setElement(eList); - return retVal; - - } - - public StructureDefinition.StructureDefinitionDifferentialComponent createTestDiff() { - StructureDefinition.StructureDefinitionDifferentialComponent retVal = new StructureDefinition.StructureDefinitionDifferentialComponent(); - List eList = new ArrayList(); - ElementDefinition ed0 = new ElementDefinition(); - // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); - // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); - ed0.setId("TestStructure"); - ed0.setSliceName("TestStructure"); - ed0.setPath("TestStructure"); - // ed0.setBase(base); - ed0.setMin(1); - ed0.setMax("1"); - eList.add(ed0); - - ElementDefinition ed = new ElementDefinition(); - // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); - // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); - ed.setId("system"); - ed.setSliceName("system"); - ed.setPath("TestStructure.system"); - // ed.setBase(base); - ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging")); - // ed.setType(this.createTypeRefList()); - eList.add(ed); - retVal.setElement(eList); return retVal; } - public StructureMap createTestStructuremap() throws Exception { - StructureMap retMap = new StructureMap(); - retMap.setUrl("http://opencimi.org/structuremap/testtransform"); - retMap.setName("TestTransform"); - retMap.setStatus(Enumerations.PublicationStatus.DRAFT); - retMap.setStructure(this.createMapStructureList()); - retMap.setGroup(this.buildTestGroup()); - return retMap; - } - - public List createMapStructureList() { - List retVal = new ArrayList(); - StructureMap.StructureMapStructureComponent source = new StructureMap.StructureMapStructureComponent(); - StructureMap.StructureMapStructureComponent target = new StructureMap.StructureMapStructureComponent(); - source.setUrl("http://opencimi.org/structuredefinition/TestStructure"); - source.setMode(StructureMap.StructureMapModelMode.SOURCE); - target.setUrl("http://hl7.org/fhir/StructureDefinition/Coding"); - target.setMode(StructureMap.StructureMapModelMode.TARGET); - retVal.add(source); - retVal.add(target); + public List buildTargetList(StructureMap.StructureMapGroupRuleTargetComponent[] sources) { + List retVal = new ArrayList(); + retVal.addAll(Arrays.asList(sources)); return retVal; } @@ -225,53 +139,6 @@ public class StructureMapTests2 { return retVal; } - public List buildSourceList(StructureMap.StructureMapGroupRuleSourceComponent[] sources) { - List retVal = new ArrayList(); - retVal.addAll(Arrays.asList(sources)); - return retVal; - } - - public StructureMap.StructureMapGroupRuleSourceComponent buildSource(String context, @Nullable String element, @Nullable String variable, @Nullable String type, @Nullable Integer min, - @Nullable String max) { - StructureMap.StructureMapGroupRuleSourceComponent retVal = new StructureMap.StructureMapGroupRuleSourceComponent(); - retVal.setContext(context); - if (element != null) - retVal.setElement(element); - if (variable != null) - retVal.setVariable(variable); - if (type != null) - retVal.setType(type); - if (min != null) - retVal.setMin(min); - if (max != null) - retVal.setMax(max); - return retVal; - } - - public List buildTargetList(StructureMap.StructureMapGroupRuleTargetComponent[] sources) { - List retVal = new ArrayList(); - retVal.addAll(Arrays.asList(sources)); - return retVal; - } - - public StructureMap.StructureMapGroupRuleTargetComponent buildTarget(@Nullable String context, @Nullable String element, @Nullable String variable, - @Nullable StructureMap.StructureMapTransform transform, @Nullable TargetParam[] params) throws Exception { - StructureMap.StructureMapGroupRuleTargetComponent retVal = new StructureMap.StructureMapGroupRuleTargetComponent(); - if (context != null) - retVal.setContext(context); - if (element != null) - retVal.setElement(element); - if (variable != null) - retVal.setVariable(variable); - if (transform != null) - retVal.setTransform(transform); - if (params != null) { - if (params.length > 0) - retVal.setParameter(this.constructParameters(params)); - } - return retVal; - } - public List constructParameters(TargetParam[] params) throws Exception { List parameterComponents = new ArrayList(); for (TargetParam tp : params) { @@ -293,29 +160,161 @@ public class StructureMapTests2 { return parameterComponents; } + public List createMapStructureList() { + List retVal = new ArrayList(); + StructureMap.StructureMapStructureComponent source = new StructureMap.StructureMapStructureComponent(); + StructureMap.StructureMapStructureComponent target = new StructureMap.StructureMapStructureComponent(); + source.setUrl("http://opencimi.org/structuredefinition/TestStructure"); + source.setMode(StructureMap.StructureMapModelMode.SOURCE); + target.setUrl("http://hl7.org/fhir/StructureDefinition/Coding"); + target.setMode(StructureMap.StructureMapModelMode.TARGET); + retVal.add(source); + retVal.add(target); + return retVal; + } + + public StructureDefinition.StructureDefinitionDifferentialComponent createTestDiff() { + StructureDefinition.StructureDefinitionDifferentialComponent retVal = new StructureDefinition.StructureDefinitionDifferentialComponent(); + List eList = new ArrayList(); + ElementDefinition ed0 = new ElementDefinition(); + // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); + // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); + ed0.setId("TestStructure"); + ed0.setSliceName("TestStructure"); + ed0.setPath("TestStructure"); + // ed0.setBase(base); + ed0.setMin(1); + ed0.setMax("1"); + eList.add(ed0); + + ElementDefinition ed = new ElementDefinition(); + // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); + // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); + ed.setId("system"); + ed.setSliceName("system"); + ed.setPath("TestStructure.system"); + // ed.setBase(base); + ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging")); + // ed.setType(this.createTypeRefList()); + eList.add(ed); + retVal.setElement(eList); + return retVal; + } + + public StructureDefinition.StructureDefinitionSnapshotComponent createTestSnapshot() { + StructureDefinition.StructureDefinitionSnapshotComponent retVal = new StructureDefinition.StructureDefinitionSnapshotComponent(); + List eList = new ArrayList(); + ElementDefinition ed0 = new ElementDefinition(); + // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); + // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); + ed0.setId("TestStructure"); + ed0.setSliceName("TestStructure"); + ed0.setPath("TestStructure"); + // ed0.setBase(base); + ed0.setMin(1); + ed0.setMax("1"); + eList.add(ed0); + + ElementDefinition ed = new ElementDefinition(); + // ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent(); + // base.setId("http://hl7.org/fhir/StructureDefinition/Element"); + ed.setId("system"); + ed.setSliceName("system"); + ed.setPath("TestStructure.system"); + // ed.setBase(base); + ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging")); + // ed.setType(this.createTypeRefList()); + ed.setMin(1); + ed.setMax("1"); + eList.add(ed); + retVal.setElement(eList); + return retVal; + + } + + public StructureDefinition createTestStructure() { + StructureDefinition sd = new StructureDefinition(); + sd.setId("TestStructure"); + sd.setUrl("http://opencimi.org/structuredefinition/TestStructure"); + sd.setStatus(Enumerations.PublicationStatus.DRAFT); + sd.setName("TestStructure"); + sd.setType("TestStructure"); + sd.setSnapshot(this.createTestSnapshot()); + sd.setDifferential(this.createTestDiff()); + sd.setKind(StructureDefinition.StructureDefinitionKind.LOGICAL); + + return sd; + } + + public StructureMap createTestStructuremap() throws Exception { + StructureMap retMap = new StructureMap(); + retMap.setUrl("http://opencimi.org/structuremap/testtransform"); + retMap.setName("TestTransform"); + retMap.setStatus(Enumerations.PublicationStatus.DRAFT); + retMap.setStructure(this.createMapStructureList()); + retMap.setGroup(this.buildTestGroup()); + return retMap; + } + + /** + * Sets up the resource paths as well as create the contexts using a defalut validator to start with. + * + * @throws Exception + */ + @Before + public void setUp() throws Exception { + if (this.context == null) { + this.context = FhirContext.forDstu3(); + } + } + + /** + * See #682 + */ + @Test + public void testMappingTransform() throws Exception { + Map maps = new HashMap(); // Instantiate a hashmap for StructureMaps + this.validationSupport = new PrePopulatedValidationSupport(); // Create Validation Instance + for (StructureDefinition sd : new DefaultProfileValidationSupport().fetchAllStructureDefinitions(this.context)) { // Read in the default Structure Definitions into a validator that allows custom + // declared structure definitions. + this.validationSupport.addStructureDefinition(sd); + } + StructureDefinition sd1 = this.createTestStructure(); // Calls a method that constructs a comp + this.validationSupport.addStructureDefinition(sd1); // Add custom structure to validation support. + this.hapiContext = new HapiWorkerContext(this.context, this.validationSupport);// Init the Hapi Work + StructureMap map = this.createTestStructuremap(); + maps.put(map.getUrl(), map); + StructureMapUtilities scu = new StructureMapUtilities(hapiContext, maps, null, null); + List result = scu.analyse(null, map).getProfiles(); + + assertEquals(1, result.size()); + + ourLog.info(context.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.get(0))); + } + public class TargetParam { + private String type; + + private String value; + public TargetParam(String type, String value) { this.type = type; this.value = value; } - private String type; - - private String value; - public String getType() { return type; } - public void setType(String type) { - this.type = type; - } - public String getValue() { return value; } + public void setType(String type) { + this.type = type; + } + public void setValue(String value) { this.value = value; } diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 710d7bc669b..c26f5d1e37b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -149,6 +149,13 @@ AuthorizationInterceptor did not permit PATCH operations to proceed even if the user had write access for the resource being patched. + + Fix an issue in HapiWorkerContext where structure definitions are + not able to be retrieved if they are referred to by their + relative or logical ID. This affects profile tooling such as + StructureMapUtilities. Thanks to Travis Lukach for reporting and + providing a test case! +