Merge branch 'master' into Add_map_compile
This commit is contained in:
commit
43fb17e5d2
|
@ -304,3 +304,4 @@ local.properties
|
|||
/org.hl7.fhir.r5/src/test/resources/snapshot-generation/logical2-actual.xml
|
||||
/org.hl7.fhir.r5.new
|
||||
/org.hl7.fhir.r5.newc
|
||||
/org.hl7.fhir.r4b.new
|
||||
|
|
|
@ -162,6 +162,7 @@ compile group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-structures-r4', version: '(l
|
|||
compile group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-structures-r5', version: '(latest version)'
|
||||
```
|
||||
|
||||
Note that the built binary validator is released through GitHub releases.
|
||||
### Maintenance
|
||||
This project is maintained by [Grahame Grieve][Link-grahameGithub], [James Agnew][Link-jamesGithub] and [Mark Iantorno][Link-markGithub] on behalf of the FHIR community.
|
||||
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
# Resource Conversion
|
||||
|
||||
##### Let's talk about converting resources between the various versions of FHIR...
|
||||
## IMPORTANT
|
||||
-----
|
||||
|
||||
_The conversion code in this module is maintained as part of the development of the standard, but always under
|
||||
considerable time pressure. Only part of the code is rigorously tested [as detailed here](#reliable-conversion-code).
|
||||
Implementers should regard this code as a 'scaffold' for actual reliable conversions._
|
||||
|
||||
**ALWAYS TEST ANY CONVERSION ROUTINES BEFORE USING THEM IN PRODUCTION!**
|
||||
|
||||
_Ideally, this should be via unit tests in your code, or better yet [unit tests contributed to FHIR](#test-cases)._
|
||||
|
||||
### A note regarding syntax
|
||||
|
||||
|
@ -31,7 +40,7 @@ and [r4](http://hl7.org/fhir/R4/account.html)
|
|||
**N.B.** This information is only for code navigation purposes. It is important that when converting between versions
|
||||
you use the provided conversion factory classes as your entry point.
|
||||
|
||||
### Using the conversion library
|
||||
## Using the conversion library
|
||||
|
||||
-----
|
||||
The majority of use cases for conversion will involve using the provided VersionConvertorFactory_V1_V2 classes to convert
|
||||
|
@ -193,3 +202,31 @@ Once you've created your new advisor, they can be provided as an argument when c
|
|||
`public static (V1 Resource) convertResource((V2 Resource) src, <T extends BaseAdvisor> advisor)`
|
||||
|
||||
`public static (V2 Resource) convertResource((V1 Resource) src, <T extends BaseAdvisor> advisor)`
|
||||
|
||||
## Development notes
|
||||
-----
|
||||
|
||||
### Reliable conversion code
|
||||
|
||||
The FHIR project maintains and tests conversions on the following resources, from old versions to R5:
|
||||
|
||||
- CodeSystem
|
||||
- ValueSet
|
||||
- ConceptMap
|
||||
- StructureDefinition
|
||||
- StructureMap
|
||||
- ImplementationGuide
|
||||
- CapabilityStatement
|
||||
- OperationDefinition
|
||||
- NamingSystem
|
||||
|
||||
These can be relied on and are subject to extensive testing.
|
||||
|
||||
### Test cases
|
||||
|
||||
Some conversions have test cases for particular resources and particular version combinations. Where test cases exist,
|
||||
they will continue to be maintained and expected to pass.
|
||||
|
||||
Contributing test cases is highly encouraged! To contribute, create a PRs to the
|
||||
[core library](https://github.com/hapifhir/org.hl7.fhir.core), or even better, to the
|
||||
[FHIR test cases library](https://github.com/FHIR/fhir-test-cases).
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
About the version conversion routines
|
||||
|
||||
The version conversion routines are maintained as part of
|
||||
the development of the standard, but always under considerable
|
||||
time pressure. Implementers should regard these as 'scaffolds' for
|
||||
an actual reliable conversion routine.
|
||||
|
||||
The FHIR project maintains and tests conversions on the following
|
||||
resources, from old versions to R5:
|
||||
* CodeSystem
|
||||
* ValueSet
|
||||
* ConceptMap
|
||||
* StructureDefinition
|
||||
* StructureMap
|
||||
* ImplementationGuide
|
||||
* CapabilityStatement
|
||||
* OperationDefinition
|
||||
* NamingSystem
|
||||
|
||||
These can be relied on and are subject to extensive testing.
|
||||
|
||||
In addition to this, some of the conversions have test cases
|
||||
for particular resources and particular version combinations.
|
||||
Where test cases exist, they will continue to pass and be
|
||||
maintained.
|
||||
|
||||
So:
|
||||
* test the conversion routines before using them in production
|
||||
* contribute test cases to ensure that your use cases continue to be reliable
|
||||
|
||||
Test cases are welcome - make them as PRs to the core library, or even better,
|
||||
to the FHIR test cases library
|
|
@ -60,8 +60,8 @@ public class Bundle10_30 {
|
|||
tgt.addLink(convertBundleLinkComponent(t));
|
||||
if (src.hasFullUrlElement())
|
||||
tgt.setFullUrlElement(Uri10_30.convertUri(src.getFullUrlElement()));
|
||||
org.hl7.fhir.dstu2.model.Resource res = ConversionContext10_30.INSTANCE.getVersionConvertor_10_30().convertResource(src.getResource());
|
||||
tgt.setResource(res);
|
||||
if (src.hasResource())
|
||||
tgt.setResource(ConversionContext10_30.INSTANCE.getVersionConvertor_10_30().convertResource(src.getResource()));
|
||||
if (src.hasSearch())
|
||||
tgt.setSearch(convertBundleEntrySearchComponent(src.getSearch()));
|
||||
if (src.hasRequest())
|
||||
|
|
|
@ -78,8 +78,8 @@ public class Bundle10_40 {
|
|||
for (org.hl7.fhir.r4.model.Bundle.BundleLinkComponent t : src.getLink()) tgt.addLink(convertBundleLinkComponent(t));
|
||||
if (src.hasFullUrlElement())
|
||||
tgt.setFullUrlElement(Uri10_40.convertUri(src.getFullUrlElement()));
|
||||
org.hl7.fhir.dstu2.model.Resource res = ConversionContext10_40.INSTANCE.getVersionConvertor_10_40().convertResource(src.getResource());
|
||||
tgt.setResource(res);
|
||||
if (src.hasResource())
|
||||
tgt.setResource(ConversionContext10_40.INSTANCE.getVersionConvertor_10_40().convertResource(src.getResource()));
|
||||
if (src.hasSearch())
|
||||
tgt.setSearch(convertBundleEntrySearchComponent(src.getSearch()));
|
||||
if (src.hasRequest())
|
||||
|
|
|
@ -78,8 +78,8 @@ public class Bundle10_50 {
|
|||
for (org.hl7.fhir.r5.model.Bundle.BundleLinkComponent t : src.getLink()) tgt.addLink(convertBundleLinkComponent(t));
|
||||
if (src.hasFullUrlElement())
|
||||
tgt.setFullUrlElement(Uri10_50.convertUri(src.getFullUrlElement()));
|
||||
org.hl7.fhir.dstu2.model.Resource res = ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().convertResource(src.getResource());
|
||||
tgt.setResource(res);
|
||||
if (src.hasResource())
|
||||
tgt.setResource(ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().convertResource(src.getResource()));
|
||||
if (src.hasSearch())
|
||||
tgt.setSearch(convertBundleEntrySearchComponent(src.getSearch()));
|
||||
if (src.hasRequest())
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package org.hl7.fhir.convertors.misc;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r4b.formats.JsonParser;
|
||||
import org.hl7.fhir.r4b.model.Bundle;
|
||||
import org.hl7.fhir.r4b.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import org.hl7.fhir.r4b.model.SearchParameter;
|
||||
import org.hl7.fhir.r4b.utils.NPMPackageGenerator;
|
||||
import org.hl7.fhir.r4b.utils.NPMPackageGenerator.Category;
|
||||
|
||||
public class ExamplesPackageBuilder {
|
||||
|
||||
public static void main(String[] args) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||
new ExamplesPackageBuilder().process(args[0]);
|
||||
|
||||
}
|
||||
|
||||
private void process(String source) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||
Set<String> set = new HashSet<>();
|
||||
for (File f : new File(source).listFiles()) {
|
||||
if (f.getName().endsWith(".json")) {
|
||||
JsonObject obj = JsonTrackingParser.parseJson(new FileInputStream(f));
|
||||
if (obj.has("resourceType") && obj.has("id")) {
|
||||
String type = obj.get("resourceType").getAsString();
|
||||
String id = obj.get("id").getAsString();
|
||||
byte[] content = TextFile.fileToBytes(f);
|
||||
if (type.equals("ConceptMap")) {
|
||||
System.out.println("convert "+f.getName());
|
||||
content = r5ToR4B(content);
|
||||
TextFile.bytesToFile(content, f);
|
||||
}
|
||||
// TextFile.bytesToFile(content, Utilities.path(dest2, type+"-"+id+".json"));
|
||||
// if (!set.contains(type+"/"+id)) {
|
||||
// set.add(type+"/"+id);
|
||||
// pck.addFile(Category.RESOURCE, type+"-"+id+".json", content);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
// pck.finish();
|
||||
//
|
||||
}
|
||||
|
||||
private byte[] r5ToR4B(byte[] content) throws FHIRFormatError, IOException {
|
||||
try {
|
||||
org.hl7.fhir.r5.model.Resource r5 = new org.hl7.fhir.r5.formats.JsonParser().parse(content);
|
||||
org.hl7.fhir.r4.model.Resource r4 = VersionConvertorFactory_40_50.convertResource(r5);
|
||||
return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(r4);
|
||||
} catch (Exception e) {
|
||||
System.out.println(" .. failed: "+e.getMessage());
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.hl7.fhir.convertors.conv10_30;
|
||||
|
||||
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_30;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Bundle10_30Test {
|
||||
|
||||
@Test
|
||||
@DisplayName("Test 10_30 bundle conversion when resource is null")
|
||||
public void testNoResourceBundleConversion() throws IOException {
|
||||
org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent bec = new org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent()
|
||||
.setRequest(
|
||||
new org.hl7.fhir.dstu3.model.Bundle.BundleEntryRequestComponent()
|
||||
.setMethod(org.hl7.fhir.dstu3.model.Bundle.HTTPVerb.DELETE)
|
||||
.setUrl("Patient?identifier=123456")
|
||||
);
|
||||
|
||||
org.hl7.fhir.dstu3.model.Bundle stu3Bundle = new org.hl7.fhir.dstu3.model.Bundle()
|
||||
.addEntry(bec);
|
||||
|
||||
org.hl7.fhir.dstu2.model.Resource dstu2Resource = VersionConvertorFactory_10_30.convertResource(stu3Bundle);
|
||||
Assertions.assertNotNull(dstu2Resource);
|
||||
Assertions.assertTrue(dstu2Resource instanceof org.hl7.fhir.dstu2.model.Bundle);
|
||||
|
||||
org.hl7.fhir.dstu2.model.Bundle dstu2Bundle = (org.hl7.fhir.dstu2.model.Bundle) dstu2Resource;
|
||||
Assertions.assertEquals(1, dstu2Bundle.getEntry().size());
|
||||
|
||||
Assertions.assertNull(dstu2Bundle.getEntry().get(0).getResource());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.hl7.fhir.convertors.conv10_40;
|
||||
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Bundle10_40Test {
|
||||
|
||||
@Test
|
||||
@DisplayName("Test 10_40 bundle conversion when resource is null")
|
||||
public void testNoResourceBundleConversion() throws IOException {
|
||||
org.hl7.fhir.r4.model.Bundle.BundleEntryComponent bec = new org.hl7.fhir.r4.model.Bundle.BundleEntryComponent()
|
||||
.setRequest(
|
||||
new org.hl7.fhir.r4.model.Bundle.BundleEntryRequestComponent()
|
||||
.setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.DELETE)
|
||||
.setUrl("Patient?identifier=123456")
|
||||
);
|
||||
|
||||
org.hl7.fhir.r4.model.Bundle r4Bundle = new org.hl7.fhir.r4.model.Bundle()
|
||||
.addEntry(bec);
|
||||
|
||||
org.hl7.fhir.dstu2.model.Resource dstu2Resource = VersionConvertorFactory_10_40.convertResource(r4Bundle);
|
||||
Assertions.assertNotNull(dstu2Resource);
|
||||
Assertions.assertTrue(dstu2Resource instanceof org.hl7.fhir.dstu2.model.Bundle);
|
||||
|
||||
org.hl7.fhir.dstu2.model.Bundle dstu2Bundle = (org.hl7.fhir.dstu2.model.Bundle) dstu2Resource;
|
||||
Assertions.assertEquals(1, dstu2Bundle.getEntry().size());
|
||||
|
||||
Assertions.assertNull(dstu2Bundle.getEntry().get(0).getResource());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.hl7.fhir.convertors.conv10_50;
|
||||
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Bundle10_50Test {
|
||||
|
||||
@Test
|
||||
@DisplayName("Test 10_50 bundle conversion when resource is null")
|
||||
public void testNoResourceBundleConversion() throws IOException {
|
||||
org.hl7.fhir.r5.model.Bundle.BundleEntryComponent bec = new org.hl7.fhir.r5.model.Bundle.BundleEntryComponent()
|
||||
.setRequest(
|
||||
new org.hl7.fhir.r5.model.Bundle.BundleEntryRequestComponent()
|
||||
.setMethod(org.hl7.fhir.r5.model.Bundle.HTTPVerb.DELETE)
|
||||
.setUrl("Patient?identifier=123456")
|
||||
);
|
||||
|
||||
org.hl7.fhir.r5.model.Bundle r5Bundle = new org.hl7.fhir.r5.model.Bundle()
|
||||
.addEntry(bec);
|
||||
|
||||
org.hl7.fhir.dstu2.model.Resource dstu2Resource = VersionConvertorFactory_10_50.convertResource(r5Bundle);
|
||||
Assertions.assertNotNull(dstu2Resource);
|
||||
Assertions.assertTrue(dstu2Resource instanceof org.hl7.fhir.dstu2.model.Bundle);
|
||||
|
||||
org.hl7.fhir.dstu2.model.Bundle dstu2Bundle = (org.hl7.fhir.dstu2.model.Bundle) dstu2Resource;
|
||||
Assertions.assertEquals(1, dstu2Bundle.getEntry().size());
|
||||
|
||||
Assertions.assertNull(dstu2Bundle.getEntry().get(0).getResource());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package org.hl7.fhir.core.generator.engine;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r4.formats.JsonParser;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CompartmentDefinition;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.SearchParameter;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||
|
||||
public class DefinitionsLoaderR4B {
|
||||
|
||||
public static Definitions load(NpmPackage npm) throws IOException {
|
||||
Definitions res = new Definitions();
|
||||
|
||||
for (String t : npm.listResources("CodeSystem")) {
|
||||
res.getCodeSystems().see((CodeSystem) load(npm, t), null);
|
||||
}
|
||||
for (String t : npm.listResources("ValueSet")) {
|
||||
res.getValuesets().see((ValueSet) load(npm, t), null);
|
||||
}
|
||||
for (String t : npm.listResources("ConceptMap")) {
|
||||
res.getConceptMaps().see((ConceptMap) load(npm, t), null);
|
||||
}
|
||||
for (String t : npm.listResources("CapabilityStatement")) {
|
||||
res.getStatements().see((CapabilityStatement) load(npm, t), null);
|
||||
}
|
||||
for (String t : npm.listResources("StructureDefinition")) {
|
||||
res.getStructures().see((StructureDefinition) load(npm, t), null);
|
||||
}
|
||||
for (String t : npm.listResources("OperationDefinition")) {
|
||||
res.getOperations().see((OperationDefinition) load(npm, t), null);
|
||||
}
|
||||
for (String t : npm.listResources("SearchParameter")) {
|
||||
res.getSearchParams().see((SearchParameter) load(npm, t), null);
|
||||
}
|
||||
for (String t : npm.listResources("CompartmentDefinition")) {
|
||||
res.getCompartments().see((CompartmentDefinition) load(npm, t), null);
|
||||
}
|
||||
// Bundle bnd = (Bundle) load(npm, "Bundle-searchParams.json");
|
||||
// if (bnd != null) {
|
||||
// for (BundleEntryComponent be : bnd.getEntry()) {
|
||||
// Resource r = be.getResource();
|
||||
// if (r instanceof CodeSystem) {
|
||||
// res.getCodeSystems().see((CodeSystem) r, null);
|
||||
// } else if (r instanceof ValueSet) {
|
||||
// res.getValuesets().see((ValueSet) r, null);
|
||||
// } else if (r instanceof ConceptMap) {
|
||||
// res.getConceptMaps().see((ConceptMap) r, null);
|
||||
// } else if (r instanceof CapabilityStatement) {
|
||||
// res.getStatements().see((CapabilityStatement) r, null);
|
||||
// } else if (r instanceof StructureDefinition) {
|
||||
// res.getStructures().see((StructureDefinition) r, null);
|
||||
// } else if (r instanceof OperationDefinition) {
|
||||
// res.getOperations().see((OperationDefinition) r, null);
|
||||
// } else if (r instanceof SearchParameter) {
|
||||
// res.getSearchParams().see((SearchParameter) r, null);
|
||||
// } else if (r instanceof CompartmentDefinition) {
|
||||
// res.getCompartments().see((CompartmentDefinition) r, null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return res;
|
||||
}
|
||||
|
||||
public static Resource load(NpmPackage npm, String t) {
|
||||
try {
|
||||
return VersionConvertorFactory_40_50.convertResource(new JsonParser().parse(npm.loadResource(t)));
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error reading "+t+": "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
package org.hl7.fhir.r4.terminologies;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class ConceptMapEngine {
|
|||
for (ConceptMapGroupComponent g : cm.getGroup()) {
|
||||
for (SourceElementComponent e : g.getElement()) {
|
||||
if (code.equals(e.getCode())) {
|
||||
if (e != null)
|
||||
if (ct != null)
|
||||
throw new FHIRException("Unable to process translate "+code+" because multiple candidate matches were found in concept map "+cm.getUrl());
|
||||
ct = e;
|
||||
cg = g;
|
||||
|
@ -94,4 +94,4 @@ public class ConceptMapEngine {
|
|||
throw new Error("Not done yet");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.hl7.fhir.r4.utils.client.network;
|
||||
|
||||
import okhttp3.*;
|
||||
import okio.Buffer;
|
||||
|
||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -26,8 +28,17 @@ public class FhirLoggingInterceptor implements Interceptor {
|
|||
public Response intercept(@Nonnull Interceptor.Chain chain) throws IOException {
|
||||
// Log Request
|
||||
Request request = chain.request();
|
||||
logger.logRequest(request.method(), request.url().toString(), new ArrayList<>(request.headers().names()),
|
||||
request.body() != null ? request.body().toString().getBytes() : null);
|
||||
List<String> hdrs = new ArrayList<>();
|
||||
for (String s : request.headers().toString().split("\\n")) {
|
||||
hdrs.add(s.trim());
|
||||
}
|
||||
byte[] cnt = null;
|
||||
if (request.body() != null) {
|
||||
Buffer buf = new Buffer();
|
||||
request.body().writeTo(buf);
|
||||
cnt = buf.readByteArray();
|
||||
}
|
||||
logger.logRequest(request.method(), request.url().toString(), hdrs, cnt);
|
||||
|
||||
// Log Response
|
||||
Response response = null;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package org.hl7.fhir.r4.terminologies;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r4.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.ConceptMap;
|
||||
import org.hl7.fhir.r4.model.Enumerations;
|
||||
import javax.annotation.Nonnull;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class ConceptMapEngineTest {
|
||||
|
||||
private static final String CONCEPT_MAP_URL = "https://test-fhir.com/ConceptMap/fake";
|
||||
public static final String SOURCE_CODE_STRING = "body-weight";
|
||||
public static final String TARGET_CODE_STRING = "vital-signs";
|
||||
|
||||
@Test
|
||||
@DisplayName("Coding is translated according to ConceptMap")
|
||||
void codingTranslate() throws IOException {
|
||||
|
||||
final ConceptMap.SourceElementComponent sourceElementComponent = getSourceElementComponent();
|
||||
|
||||
final ConceptMapEngine conceptMapEngine = getConceptMapEngine(Arrays.asList(sourceElementComponent));
|
||||
Coding coding = new Coding(null, SOURCE_CODE_STRING, "Body Weight");
|
||||
|
||||
Coding actual = conceptMapEngine.translate(coding, CONCEPT_MAP_URL);
|
||||
|
||||
assertEquals(TARGET_CODE_STRING, actual.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Coding fails to translate due to multiple candidate matches in ConceptMap")
|
||||
void codingTranslateFailsForMultipleCandidateMatches() throws IOException {
|
||||
|
||||
final ConceptMap.SourceElementComponent sourceElementComponent = getSourceElementComponent();
|
||||
|
||||
final ConceptMapEngine conceptMapEngine = getConceptMapEngine(Arrays.asList(sourceElementComponent,
|
||||
sourceElementComponent
|
||||
));
|
||||
Coding coding = new Coding(null, SOURCE_CODE_STRING, "Body Weight");
|
||||
|
||||
assertThrows(FHIRException.class, () -> {
|
||||
conceptMapEngine.translate(coding, CONCEPT_MAP_URL);
|
||||
});
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private ConceptMapEngine getConceptMapEngine(Collection<ConceptMap.SourceElementComponent> elements) throws IOException {
|
||||
ConceptMap conceptMap = getConceptMap(elements);
|
||||
|
||||
SimpleWorkerContext simpleWorkerContext = mock(SimpleWorkerContext.class);
|
||||
when(simpleWorkerContext.fetchResource(ConceptMap.class, CONCEPT_MAP_URL)).thenReturn(conceptMap);
|
||||
|
||||
return new ConceptMapEngine(simpleWorkerContext);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private ConceptMap.SourceElementComponent getSourceElementComponent() {
|
||||
ConceptMap.TargetElementComponent targetElementComponent = new ConceptMap.TargetElementComponent();
|
||||
targetElementComponent.setCode(TARGET_CODE_STRING);
|
||||
targetElementComponent.setEquivalence(Enumerations.ConceptMapEquivalence.EQUIVALENT);
|
||||
|
||||
ConceptMap.SourceElementComponent sourceElementComponent = new ConceptMap.SourceElementComponent();
|
||||
sourceElementComponent.setCode(SOURCE_CODE_STRING);
|
||||
sourceElementComponent.setTarget(Collections.singletonList(targetElementComponent));
|
||||
|
||||
return sourceElementComponent;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private ConceptMap getConceptMap(Collection<ConceptMap.SourceElementComponent> elements) {
|
||||
|
||||
ConceptMap.ConceptMapGroupComponent conceptMapGroupComponent = new ConceptMap.ConceptMapGroupComponent();
|
||||
for (ConceptMap.SourceElementComponent element : elements) {
|
||||
conceptMapGroupComponent.addElement(element);
|
||||
}
|
||||
return new ConceptMap()
|
||||
.addGroup(conceptMapGroupComponent)
|
||||
.setUrl(CONCEPT_MAP_URL);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.hl7.fhir.r4b.utils.client.network;
|
||||
|
||||
import okhttp3.*;
|
||||
import okio.Buffer;
|
||||
|
||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -26,8 +28,17 @@ public class FhirLoggingInterceptor implements Interceptor {
|
|||
public Response intercept(@Nonnull Interceptor.Chain chain) throws IOException {
|
||||
// Log Request
|
||||
Request request = chain.request();
|
||||
logger.logRequest(request.method(), request.url().toString(), new ArrayList<>(request.headers().names()),
|
||||
request.body() != null ? request.body().toString().getBytes() : null);
|
||||
List<String> hdrs = new ArrayList<>();
|
||||
for (String s : request.headers().toString().split("\\n")) {
|
||||
hdrs.add(s.trim());
|
||||
}
|
||||
byte[] cnt = null;
|
||||
if (request.body() != null) {
|
||||
Buffer buf = new Buffer();
|
||||
request.body().writeTo(buf);
|
||||
cnt = buf.readByteArray();
|
||||
}
|
||||
logger.logRequest(request.method(), request.url().toString(), hdrs, cnt);
|
||||
|
||||
// Log Response
|
||||
Response response = null;
|
||||
|
|
|
@ -106,7 +106,7 @@ public class NarrativeGenerationTests {
|
|||
}
|
||||
|
||||
public static Stream<Arguments> data() throws ParserConfigurationException, IOException, FHIRFormatError, SAXException {
|
||||
Document tests = XMLUtil.parseToDom(TestingUtilities.loadTestResource("r5", "narrative", "manifest.xml"));
|
||||
Document tests = XMLUtil.parseToDom(TestingUtilities.loadTestResource("r4b", "narrative", "manifest.xml"));
|
||||
Element test = XMLUtil.getFirstChild(tests.getDocumentElement());
|
||||
List<Arguments> objects = new ArrayList<>();
|
||||
while (test != null && test.getNodeName().equals("test")) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -45,14 +45,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
|
||||
public class ProfileComparison extends CanonicalResourceComparison<StructureDefinition> {
|
||||
|
||||
private StructuralMatch<ElementDefinition> combined;
|
||||
private StructuralMatch<ElementDefinitionNode> combined;
|
||||
|
||||
public ProfileComparison(StructureDefinition left, StructureDefinition right) {
|
||||
super(left, right);
|
||||
combined = new StructuralMatch<ElementDefinition>(); // base
|
||||
combined = new StructuralMatch<ElementDefinitionNode>(); // base
|
||||
}
|
||||
|
||||
public StructuralMatch<ElementDefinition> getCombined() {
|
||||
public StructuralMatch<ElementDefinitionNode> getCombined() {
|
||||
return combined;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,21 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
}
|
||||
|
||||
|
||||
|
||||
private class ElementDefinitionNode {
|
||||
private ElementDefinition def;
|
||||
private StructureDefinition src;
|
||||
private ElementDefinitionNode(StructureDefinition src, ElementDefinition def) {
|
||||
super();
|
||||
this.src = src;
|
||||
this.def = def;
|
||||
}
|
||||
public ElementDefinition getDef() {
|
||||
return def;
|
||||
}
|
||||
public StructureDefinition getSrc() {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
|
||||
private ProfileUtilities utilsLeft;
|
||||
private ProfileUtilities utilsRight;
|
||||
|
@ -127,7 +141,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (left.getType().equals(right.getType())) {
|
||||
DefinitionNavigator ln = new DefinitionNavigator(session.getContextLeft(), left);
|
||||
DefinitionNavigator rn = new DefinitionNavigator(session.getContextRight(), right);
|
||||
StructuralMatch<ElementDefinition> sm = new StructuralMatch<ElementDefinition>(ln.current(), rn.current());
|
||||
StructuralMatch<ElementDefinitionNode> sm = new StructuralMatch<ElementDefinitionNode>(new ElementDefinitionNode(left, ln.current()), new ElementDefinitionNode(right, rn.current()));
|
||||
compareElements(res, sm, ln.path(), null, ln, rn);
|
||||
res.combined = sm;
|
||||
}
|
||||
|
@ -147,7 +161,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
throw new DefinitionException("StructureDefinition snapshot is empty ("+name+": "+sd.getName()+")");
|
||||
}
|
||||
|
||||
private void compareElements(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String sliceName, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, FHIRFormatError, IOException {
|
||||
private void compareElements(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String sliceName, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, FHIRFormatError, IOException {
|
||||
assert(path != null);
|
||||
assert(left != null);
|
||||
assert(right != null);
|
||||
|
@ -190,7 +204,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
subset.setExample(left.current().hasExample() ? left.current().getExample() : right.current().getExample());
|
||||
|
||||
if (left.current().getMustSupport() != right.current().getMustSupport()) {
|
||||
vm(IssueSeverity.ERROR, "Elements differ in definition for mustSupport:\r\n \""+left.current().getMustSupport()+"\"\r\n \""+right.current().getMustSupport()+"\"", path, comp.getMessages(), res.getMessages());
|
||||
vm(IssueSeverity.WARNING, "Elements differ in definition for mustSupport: '"+left.current().getMustSupport()+"' vs '"+right.current().getMustSupport()+"'", path, comp.getMessages(), res.getMessages());
|
||||
|
||||
}
|
||||
subset.setMustSupport(left.current().getMustSupport() || right.current().getMustSupport());
|
||||
|
@ -198,15 +212,20 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
|
||||
|
||||
// compare and intersect
|
||||
superset.setMin(unionMin(left.current().getMin(), right.current().getMin()));
|
||||
superset.setMax(unionMax(left.current().getMax(), right.current().getMax()));
|
||||
subset.setMin(intersectMin(left.current().getMin(), right.current().getMin()));
|
||||
subset.setMax(intersectMax(left.current().getMax(), right.current().getMax()));
|
||||
rule(comp, res, subset.getMax().equals("*") || Integer.parseInt(subset.getMax()) >= subset.getMin(), path, "Cardinality Mismatch: "+card(left)+"/"+card(right));
|
||||
int leftMin = left.current().getMin();
|
||||
int rightMin = right.current().getMin();
|
||||
int leftMax = "*".equals(left.current().getMax()) ? Integer.MAX_VALUE : Integer.parseInt(left.current().getMax());
|
||||
int rightMax = "*".equals(right.current().getMax()) ? Integer.MAX_VALUE : Integer.parseInt(right.current().getMax());
|
||||
|
||||
checkMinMax(comp, res, path, leftMin, rightMin, leftMax, rightMax);
|
||||
superset.setMin(unionMin(leftMin, rightMin));
|
||||
superset.setMax(unionMax(leftMax, rightMax, left.current().getMax(), right.current().getMax()));
|
||||
subset.setMin(intersectMin(leftMin, rightMin));
|
||||
subset.setMax(intersectMax(leftMax, rightMax, left.current().getMax(), right.current().getMax()));
|
||||
|
||||
superset.getType().addAll(unionTypes(comp, res, path, left.current().getType(), right.current().getType()));
|
||||
subset.getType().addAll(intersectTypes(comp, res, subset, path, left.current().getType(), right.current().getType()));
|
||||
rule(comp, res, !subset.getType().isEmpty() || (!left.current().hasType() && !right.current().hasType()), path, "Type Mismatch:\r\n "+typeCode(left)+"\r\n "+typeCode(right));
|
||||
rule(comp, res, !subset.getType().isEmpty() || (!left.current().hasType() && !right.current().hasType()), path, "Type Mismatch: "+typeCode(left)+" vs "+typeCode(right));
|
||||
// <fixed[x]><!-- ?? 0..1 * Value must be exactly this --></fixed[x]>
|
||||
// <pattern[x]><!-- ?? 0..1 * Value must have at least these property values --></pattern[x]>
|
||||
superset.setMaxLengthElement(unionMaxLength(left.current().getMaxLength(), right.current().getMaxLength()));
|
||||
|
@ -283,7 +302,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
// return null;
|
||||
}
|
||||
|
||||
private void compareChildren(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
|
||||
private void compareChildren(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
List<DefinitionNavigator> lc = left.children();
|
||||
List<DefinitionNavigator> rc = right.children();
|
||||
// it's possible that one of these profiles walks into a data type and the other doesn't
|
||||
|
@ -299,10 +319,10 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
DefinitionNavigator r = findInList(rc, l);
|
||||
if (r == null) {
|
||||
comp.getUnion().getSnapshot().getElement().add(l.current().copy());
|
||||
res.getChildren().add(new StructuralMatch<ElementDefinition>(l.current(), vmI(IssueSeverity.INFORMATION, "Removed this element", path)));
|
||||
res.getChildren().add(new StructuralMatch<ElementDefinitionNode>(new ElementDefinitionNode(l.getStructure(), l.current()), vmI(IssueSeverity.INFORMATION, "Removed this element", path)));
|
||||
} else {
|
||||
matchR.add(r);
|
||||
StructuralMatch<ElementDefinition> sm = new StructuralMatch<ElementDefinition>(l.current(), r.current());
|
||||
StructuralMatch<ElementDefinitionNode> sm = new StructuralMatch<ElementDefinitionNode>(new ElementDefinitionNode(l.getStructure(), l.current()), new ElementDefinitionNode(r.getStructure(), r.current()));
|
||||
res.getChildren().add(sm);
|
||||
compareElements(comp, sm, l.path(), null, l, r);
|
||||
}
|
||||
|
@ -310,7 +330,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
for (DefinitionNavigator r : rc) {
|
||||
if (!matchR.contains(r)) {
|
||||
comp.getUnion().getSnapshot().getElement().add(r.current().copy());
|
||||
res.getChildren().add(new StructuralMatch<ElementDefinition>(vmI(IssueSeverity.INFORMATION, "Added this element", path), r.current()));
|
||||
res.getChildren().add(new StructuralMatch<ElementDefinitionNode>(vmI(IssueSeverity.INFORMATION, "Added this element", path), new ElementDefinitionNode(r.getStructure(), r.current())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +344,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void ruleEqual(ProfileComparison comp, StructuralMatch<ElementDefinition> res, DataType vLeft, DataType vRight, String name, String path) throws IOException {
|
||||
private void ruleEqual(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, DataType vLeft, DataType vRight, String name, String path) throws IOException {
|
||||
if (vLeft == null && vRight == null) {
|
||||
// nothing
|
||||
} else if (vLeft == null) {
|
||||
|
@ -338,7 +358,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
|
||||
private String toString(DataType val, boolean left) throws IOException {
|
||||
if (val instanceof PrimitiveType)
|
||||
return "\"" + ((PrimitiveType) val).getValueAsString()+"\"";
|
||||
return "'" + ((PrimitiveType) val).getValueAsString()+"'";
|
||||
|
||||
IParser jp = left ? session.getContextLeft().newJsonParser() : session.getContextRight().newJsonParser();
|
||||
return jp.composeString(val, "value");
|
||||
|
@ -356,14 +376,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return s;
|
||||
}
|
||||
|
||||
private boolean rule(ProfileComparison comp, StructuralMatch<ElementDefinition> res, boolean test, String path, String message) {
|
||||
private boolean rule(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, boolean test, String path, String message) {
|
||||
if (!test) {
|
||||
vm(IssueSeverity.ERROR, message, path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
return test;
|
||||
}
|
||||
|
||||
private String mergeText(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String name, String left, String right, boolean isError) {
|
||||
private String mergeText(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String name, String left, String right, boolean isError) {
|
||||
if (left == null && right == null)
|
||||
return null;
|
||||
if (left == null)
|
||||
|
@ -375,7 +395,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (left.equalsIgnoreCase(right))
|
||||
return left;
|
||||
if (path != null) {
|
||||
vm(isError ? IssueSeverity.ERROR : IssueSeverity.WARNING, "Elements differ in "+name+":\r\n \""+left+"\"\r\n \""+right+"\"", path, comp.getMessages(), res.getMessages());
|
||||
vm(isError ? IssueSeverity.ERROR : IssueSeverity.WARNING, "Elements differ in "+name+": '"+left+"' vs '"+right+"'", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
return "left: "+left+"; right: "+right;
|
||||
}
|
||||
|
@ -429,6 +449,36 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return right;
|
||||
}
|
||||
|
||||
private void checkMinMax(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, int leftMin, int rightMin, int leftMax, int rightMax) {
|
||||
if (leftMin != rightMin) {
|
||||
if (leftMin == 0) {
|
||||
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ: '"+leftMin+"' vs '"+rightMin+"'", path, comp.getMessages(), res.getMessages());
|
||||
} else if (rightMin == 0) {
|
||||
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ: '"+leftMin+"' vs '"+rightMin+"'", path, comp.getMessages(), res.getMessages());
|
||||
} else {
|
||||
vm(IssueSeverity.INFORMATION, "Element minimum cardinalities differ: '"+leftMin+"' vs '"+rightMin+"'", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
}
|
||||
if (leftMax != rightMax) {
|
||||
if (leftMax == Integer.MAX_VALUE) {
|
||||
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ: '"+leftMax+"' vs '"+rightMax+"'", path, comp.getMessages(), res.getMessages());
|
||||
} else if (rightMax == Integer.MAX_VALUE) {
|
||||
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ: '"+leftMax+"' vs '"+rightMax+"'", path, comp.getMessages(), res.getMessages());
|
||||
} else {
|
||||
vm(IssueSeverity.INFORMATION, "Element maximum cardinalities differ: '"+leftMax+"' vs '"+rightMax+"'", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
}
|
||||
// rule(comp, res, subset.getMax().equals("*") || Integer.parseInt(subset.getMax()) >= subset.getMin(), path, "Cardinality Mismatch: "+card(left)+"/"+card(right));
|
||||
|
||||
// cross comparison - if max > min in either direction, there can be no instances that are valid against both
|
||||
if (leftMax < rightMin) {
|
||||
vm(IssueSeverity.ERROR, "Element minimum cardinalities conflict: '"+leftMin+".."+leftMax+"' vs '"+rightMin+".."+rightMax+"': No instances can be valid against both profiles", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
if (rightMax < leftMin) {
|
||||
vm(IssueSeverity.ERROR, "Element minimum cardinalities conflict: '"+leftMin+".."+leftMax+"' vs '"+rightMin+".."+rightMax+"': No instances can be valid against both profiles", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
}
|
||||
|
||||
private int unionMin(int left, int right) {
|
||||
if (left > right)
|
||||
return right;
|
||||
|
@ -436,18 +486,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return left;
|
||||
}
|
||||
|
||||
private String intersectMax(String left, String right) {
|
||||
int l = "*".equals(left) ? Integer.MAX_VALUE : Integer.parseInt(left);
|
||||
int r = "*".equals(right) ? Integer.MAX_VALUE : Integer.parseInt(right);
|
||||
private String intersectMax(int l, int r, String left, String right) {
|
||||
if (l < r)
|
||||
return left;
|
||||
else
|
||||
return right;
|
||||
}
|
||||
|
||||
private String unionMax(String left, String right) {
|
||||
int l = "*".equals(left) ? Integer.MAX_VALUE : Integer.parseInt(left);
|
||||
int r = "*".equals(right) ? Integer.MAX_VALUE : Integer.parseInt(right);
|
||||
private String unionMax(int l, int r, String left, String right) {
|
||||
if (l < r)
|
||||
return right;
|
||||
else
|
||||
|
@ -480,7 +526,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return Integer.toString(defn.current().getMin())+".."+defn.current().getMax();
|
||||
}
|
||||
|
||||
private Collection<? extends TypeRefComponent> unionTypes(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
private Collection<? extends TypeRefComponent> unionTypes(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
||||
for (TypeRefComponent l : left)
|
||||
checkAddTypeUnion(comp, res, path, result, l, session.getContextLeft());
|
||||
|
@ -489,7 +535,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<TypeRefComponent> results, TypeRefComponent nw, IWorkerContext ctxt) throws DefinitionException, IOException, FHIRFormatError {
|
||||
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> results, TypeRefComponent nw, IWorkerContext ctxt) throws DefinitionException, IOException, FHIRFormatError {
|
||||
boolean pfound = false;
|
||||
boolean tfound = false;
|
||||
nw = nw.copy();
|
||||
|
@ -586,7 +632,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return false;
|
||||
}
|
||||
|
||||
private Collection<? extends TypeRefComponent> intersectTypes(ProfileComparison comp, StructuralMatch<ElementDefinition> res, ElementDefinition ed, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
private Collection<? extends TypeRefComponent> intersectTypes(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, ElementDefinition ed, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
||||
for (TypeRefComponent l : left) {
|
||||
if (l.hasAggregation())
|
||||
|
@ -665,7 +711,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
private boolean compareBindings(ProfileComparison comp, StructuralMatch<ElementDefinition> res, ElementDefinition subset, ElementDefinition superset, String path, ElementDefinition lDef, ElementDefinition rDef) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private boolean compareBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, ElementDefinition subset, ElementDefinition superset, String path, ElementDefinition lDef, ElementDefinition rDef) throws FHIRFormatError, DefinitionException, IOException {
|
||||
assert(lDef.hasBinding() || rDef.hasBinding());
|
||||
if (!lDef.hasBinding()) {
|
||||
subset.setBinding(rDef.getBinding());
|
||||
|
@ -801,7 +847,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
}
|
||||
|
||||
// we can't really know about constraints. We create warnings, and collate them
|
||||
private List<ElementDefinitionConstraintComponent> unionConstraints(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<ElementDefinitionConstraintComponent> left, List<ElementDefinitionConstraintComponent> right) {
|
||||
private List<ElementDefinitionConstraintComponent> unionConstraints(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<ElementDefinitionConstraintComponent> left, List<ElementDefinitionConstraintComponent> right) {
|
||||
List<ElementDefinitionConstraintComponent> result = new ArrayList<ElementDefinitionConstraintComponent>();
|
||||
for (ElementDefinitionConstraintComponent l : left) {
|
||||
boolean found = false;
|
||||
|
@ -829,7 +875,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return result;
|
||||
}
|
||||
|
||||
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String url, String name, IWorkerContext ctxt) {
|
||||
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String url, String name, IWorkerContext ctxt) {
|
||||
StructureDefinition sd = ctxt.fetchResource(StructureDefinition.class, url);
|
||||
if (sd == null) {
|
||||
ValidationMessage vm = vmI(IssueSeverity.WARNING, "Unable to resolve profile "+url+" in profile "+name, path);
|
||||
|
@ -841,7 +887,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return binding.getStrength() == BindingStrength.EXAMPLE || binding.getStrength() == BindingStrength.PREFERRED;
|
||||
}
|
||||
|
||||
private ElementDefinitionBindingComponent unionBindings(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, ElementDefinitionBindingComponent left, ElementDefinitionBindingComponent right) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private ElementDefinitionBindingComponent unionBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, ElementDefinitionBindingComponent left, ElementDefinitionBindingComponent right) throws FHIRFormatError, DefinitionException, IOException {
|
||||
ElementDefinitionBindingComponent union = new ElementDefinitionBindingComponent();
|
||||
if (left.getStrength().compareTo(right.getStrength()) < 0)
|
||||
union.setStrength(left.getStrength());
|
||||
|
@ -881,17 +927,17 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return gen.generate(model, prefix, 0, null);
|
||||
}
|
||||
|
||||
private void genElementComp(String defPath, HierarchicalTableGenerator gen, List<Row> rows, StructuralMatch<ElementDefinition> combined, String corePath, String prefix, Row slicingRow, boolean root) throws IOException {
|
||||
private void genElementComp(String defPath, HierarchicalTableGenerator gen, List<Row> rows, StructuralMatch<ElementDefinitionNode> combined, String corePath, String prefix, Row slicingRow, boolean root) throws IOException {
|
||||
Row originalRow = slicingRow;
|
||||
Row typesRow = null;
|
||||
|
||||
List<StructuralMatch<ElementDefinition>> children = combined.getChildren();
|
||||
List<StructuralMatch<ElementDefinitionNode>> children = combined.getChildren();
|
||||
|
||||
Row row = gen.new Row();
|
||||
rows.add(row);
|
||||
String path = combined.either().getPath();
|
||||
String path = combined.either().getDef().getPath();
|
||||
row.setAnchor(path);
|
||||
row.setColor(utilsRight.getRowColor(combined.either(), false));
|
||||
row.setColor(utilsRight.getRowColor(combined.either().getDef(), false));
|
||||
if (eitherHasSlicing(combined))
|
||||
row.setLineColor(1);
|
||||
else if (eitherHasSliceName(combined))
|
||||
|
@ -917,7 +963,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
row.setIcon("icon_choice.gif", HierarchicalTableGenerator.TEXT_ICON_CHOICE);
|
||||
typesRow = row;
|
||||
}
|
||||
} else if (combined.either().hasContentReference())
|
||||
} else if (combined.either().getDef().hasContentReference())
|
||||
row.setIcon("icon_reuse.png", HierarchicalTableGenerator.TEXT_ICON_REUSE);
|
||||
else if (isPrimitive(combined))
|
||||
row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||
|
@ -927,7 +973,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||
else
|
||||
row.setIcon("icon_resource.png", HierarchicalTableGenerator.TEXT_ICON_RESOURCE);
|
||||
String ref = defPath == null ? null : defPath + combined.either().getId();
|
||||
String ref = defPath == null ? null : defPath + combined.either().getDef().getId();
|
||||
String sName = tail(path);
|
||||
String sn = getSliceName(combined);
|
||||
if (sn != null)
|
||||
|
@ -937,23 +983,23 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
String leftColor = !combined.hasLeft() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||
String rightColor = !combined.hasRight() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||
if (combined.hasLeft()) {
|
||||
nc = utilsRight.genElementNameCell(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
nc = utilsRight.genElementNameCell(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, false, ext, used , ref, sName);
|
||||
} else {
|
||||
nc = utilsRight.genElementNameCell(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
nc = utilsRight.genElementNameCell(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, false, ext, used , ref, sName);
|
||||
}
|
||||
if (combined.hasLeft()) {
|
||||
frame(utilsRight.genElementCells(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName, nc, false), leftColor);
|
||||
frame(utilsRight.genElementCells(gen, combined.getLeft().getDef(), "??", true, corePath, prefix, root, false, false, combined.getLeft().getSrc(), typesRow, row, true, ext, used , ref, sName, nc, false, false), leftColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), leftColor);
|
||||
}
|
||||
if (combined.hasRight()) {
|
||||
frame(utilsRight.genElementCells(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used, ref, sName, nc, false), rightColor);
|
||||
frame(utilsRight.genElementCells(gen, combined.getRight().getDef(), "??", true, corePath, prefix, root, false, false, combined.getRight().getSrc(), typesRow, row, true, ext, used, ref, sName, nc, false, false), rightColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), rightColor);
|
||||
}
|
||||
row.getCells().add(cellForMessages(gen, combined.getMessages()));
|
||||
|
||||
for (StructuralMatch<ElementDefinition> child : children) {
|
||||
for (StructuralMatch<ElementDefinitionNode> child : children) {
|
||||
genElementComp(defPath, gen, row.getSubRows(), child, corePath, prefix, originalRow, false);
|
||||
}
|
||||
}
|
||||
|
@ -978,47 +1024,47 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return res;
|
||||
}
|
||||
|
||||
private String getSliceName(StructuralMatch<ElementDefinition> combined) {
|
||||
private String getSliceName(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isDataType(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean isDataType(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasTarget(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean hasTarget(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isPrimitive(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean isPrimitive(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allAreReference(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean allAreReference(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasChoice(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean hasChoice(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean elementIsComplex(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean elementIsComplex(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub velement.hasType() && element.getType().get(0).hasProfile() && extensionIsComplex(element.getType().get(0).getProfile().get(0).getValue()
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean eitherHasSliceName(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean eitherHasSliceName(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean eitherHasSlicing(StructuralMatch<ElementDefinition> combined) {
|
||||
private boolean eitherHasSlicing(StructuralMatch<ElementDefinitionNode> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -301,11 +301,11 @@ public class ResourceComparer {
|
|||
private String halfColorForLevel(IssueSeverity level) {
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
return "#ffeeee";
|
||||
return "#ffdddd";
|
||||
case FATAL:
|
||||
return "#ffcccc";
|
||||
case WARNING:
|
||||
return "#fff4ee";
|
||||
return "#fff6ee";
|
||||
default: // INFORMATION:
|
||||
return "#fffff2";
|
||||
}
|
||||
|
@ -319,6 +319,9 @@ public class ResourceComparer {
|
|||
XhtmlNode li = new XhtmlNode(NodeType.Element, "li");
|
||||
piece.getChildren().add(li);
|
||||
li.style("background-color: "+halfColorForLevel(msg.getLevel()));
|
||||
if (msg.getLevel() == IssueSeverity.ERROR) {
|
||||
li.style("font-weight: bold");
|
||||
}
|
||||
li.tx(msg.getMessage());
|
||||
}
|
||||
return cell;
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
|
||||
|
@ -113,5 +114,6 @@ public class StructuralMatch<T> {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -36,6 +36,9 @@ import java.io.FileReader;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -2087,6 +2090,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
private void removeStatusExtensions(ElementDefinition outcome) {
|
||||
outcome.removeExtension(ToolingExtensions.EXT_FMM_LEVEL);
|
||||
outcome.removeExtension(ToolingExtensions.EXT_FMM_SUPPORT);
|
||||
outcome.removeExtension(ToolingExtensions.EXT_FMM_DERIVED);
|
||||
outcome.removeExtension(ToolingExtensions.EXT_STANDARDS_STATUS);
|
||||
outcome.removeExtension(ToolingExtensions.EXT_NORMATIVE_VERSION);
|
||||
outcome.removeExtension(ToolingExtensions.EXT_WORKGROUP);
|
||||
|
@ -3502,7 +3507,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
List<TypeRefComponent> types = e.getType();
|
||||
if (!e.hasType()) {
|
||||
if (root) { // we'll use base instead of types then
|
||||
StructureDefinition bsd = context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
|
||||
StructureDefinition bsd = profile == null ? null : context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
|
||||
if (bsd != null) {
|
||||
if (bsd.hasUserData("path")) {
|
||||
c.getPieces().add(gen.new Piece(Utilities.isAbsoluteUrl(bsd.getUserString("path")) ? bsd.getUserString("path") : imagePath +bsd.getUserString("path"), bsd.getName(), null));
|
||||
|
@ -3584,7 +3589,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.addPiece(checkForNoChange(tl, gen.new Piece(null,", ", null)));
|
||||
}
|
||||
|
||||
ref = pkp.getLinkForProfile(profile, p.getValue());
|
||||
ref = pkp == null ? null : pkp.getLinkForProfile(profile, p.getValue());
|
||||
if (ref != null) {
|
||||
String[] parts = ref.split("\\|");
|
||||
if (parts[0].startsWith("http:") || parts[0].startsWith("https:")) {
|
||||
|
@ -3683,7 +3688,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
|
||||
private String checkPrepend(String corePath, String path) {
|
||||
if (pkp.prependLinks() && !(path.startsWith("http:") || path.startsWith("https:")))
|
||||
if (pkp != null && pkp.prependLinks() && !(path.startsWith("http:") || path.startsWith("https:")))
|
||||
return corePath+path;
|
||||
else
|
||||
return path;
|
||||
|
@ -4055,7 +4060,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (logicalModel && element.hasRepresentation(PropertyRepresentation.XMLATTR))
|
||||
sName = "@"+sName;
|
||||
Cell nc = genElementNameCell(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName);
|
||||
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc, mustSupport);
|
||||
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc, mustSupport, true);
|
||||
if (element.hasSlicing()) {
|
||||
if (standardExtensionSlicing(element)) {
|
||||
used.used = true; // doesn't matter whether we have a type, we're used if we're setting up slicing ... element.hasType() && element.getType().get(0).hasProfile();
|
||||
|
@ -4183,7 +4188,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
public List<Cell> genElementCells(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
||||
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
||||
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell, boolean mustSupport) throws IOException {
|
||||
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell, boolean mustSupport, boolean allowSubRows) throws IOException {
|
||||
List<Cell> res = new ArrayList<>();
|
||||
Cell gc = gen.new Cell();
|
||||
row.getCells().add(gc);
|
||||
|
@ -4209,7 +4214,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (extDefn == null) {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
res.add(addCell(row, gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null)));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows));
|
||||
} else {
|
||||
String name = urltail(eurl);
|
||||
nameCell.getPieces().get(0).setText(name);
|
||||
|
@ -4222,7 +4227,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
else // if it's complex, we just call it nothing
|
||||
// genTypes(gen, row, extDefn.getSnapshot().getElement().get(0), profileBaseFileName, profile);
|
||||
res.add(addCell(row, gen.new Cell(null, null, "("+translate("sd.table", "Complex")+")", null, null)));
|
||||
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot, mustSupport));
|
||||
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot, mustSupport, allowSubRows));
|
||||
}
|
||||
} else {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
|
@ -4230,7 +4235,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
res.add(addCell(row, gen.new Cell()));
|
||||
else
|
||||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows));
|
||||
}
|
||||
} else {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
|
@ -4238,7 +4243,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
|
||||
else
|
||||
res.add(addCell(row, gen.new Cell()));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -4544,11 +4549,11 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
&& element.getSlicing().getRules() != SlicingRules.CLOSED && element.getSlicing().getDiscriminator().size() == 1 && element.getSlicing().getDiscriminator().get(0).getPath().equals("url") && element.getSlicing().getDiscriminator().get(0).getType().equals(DiscriminatorType.VALUE);
|
||||
}
|
||||
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly) throws IOException, FHIRException {
|
||||
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly);
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows) throws IOException, FHIRException {
|
||||
return generateDescription(gen, row, definition, fallback, used, baseURL, url, profile, corePath, imagePath, root, logicalModel, allInvariants, null, snapshot, mustSupportOnly, allowSubRows);
|
||||
}
|
||||
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot, boolean mustSupportOnly) throws IOException, FHIRException {
|
||||
private Cell generateDescription(HierarchicalTableGenerator gen, Row row, ElementDefinition definition, ElementDefinition fallback, boolean used, String baseURL, String url, StructureDefinition profile, String corePath, String imagePath, boolean root, boolean logicalModel, boolean allInvariants, ElementDefinition valueDefn, boolean snapshot, boolean mustSupportOnly, boolean allowSubRows) throws IOException, FHIRException {
|
||||
Cell c = gen.new Cell();
|
||||
row.getCells().add(c);
|
||||
|
||||
|
@ -4564,7 +4569,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
if (root) {
|
||||
if (profile.getAbstract()) {
|
||||
if (profile != null && profile.getAbstract()) {
|
||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||
c.addPiece(gen.new Piece(null, "This is an abstract profile", null));
|
||||
}
|
||||
|
@ -4659,7 +4664,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (binding!=null && !binding.isEmpty()) {
|
||||
if (!c.getPieces().isEmpty())
|
||||
c.addPiece(gen.new Piece("br"));
|
||||
BindingResolution br = pkp.resolveBinding(profile, binding, definition.getPath());
|
||||
BindingResolution br = pkp == null ? makeNullBr(binding) : pkp.resolveBinding(profile, binding, definition.getPath());
|
||||
c.getPieces().add(checkForNoChange(binding, gen.new Piece(null, translate("sd.table", "Binding")+": ", null).addStyle("font-weight:bold")));
|
||||
c.getPieces().add(checkForNoChange(binding.getValueSetElement(), gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null)));
|
||||
if (binding.hasStrength()) {
|
||||
|
@ -4668,7 +4673,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(checkForNoChange(binding.getStrengthElement(), gen.new Piece(null, ")", null)));
|
||||
}
|
||||
if (binding.hasExtension(ToolingExtensions.EXT_MAX_VALUESET)) {
|
||||
br = pkp.resolveBinding(profile, ToolingExtensions.readStringExtension(binding, ToolingExtensions.EXT_MAX_VALUESET), definition.getPath());
|
||||
br = pkp == null ? makeNullBr(binding) : pkp.resolveBinding(profile, ToolingExtensions.readStringExtension(binding, ToolingExtensions.EXT_MAX_VALUESET), definition.getPath());
|
||||
c.addPiece(gen.new Piece("br"));
|
||||
c.getPieces().add(checkForNoChange(binding, gen.new Piece(corePath+"extension-elementdefinition-maxvalueset.html", translate("sd.table", "Max Binding")+": ", "Max Value Set Extension").addStyle("font-weight:bold")));
|
||||
c.getPieces().add(checkForNoChange(binding, gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath+br.url, br.display, null)));
|
||||
|
@ -4704,7 +4709,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (definition.hasFixed()) {
|
||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, translate("sd.table", "Fixed Value")+": ", null).addStyle("font-weight:bold")));
|
||||
if (!useTableForFixedValues || definition.getFixed().isPrimitive()) {
|
||||
if (!useTableForFixedValues || !allowSubRows || definition.getFixed().isPrimitive()) {
|
||||
String s = buildJson(definition.getFixed());
|
||||
String link = null;
|
||||
if (Utilities.isAbsoluteUrl(s))
|
||||
|
@ -4712,7 +4717,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(link, s, null).addStyle("color: darkgreen")));
|
||||
} else {
|
||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "As shown", null).addStyle("color: darkgreen")));
|
||||
genFixedValue(gen, row, definition.getFixed(), snapshot, false, corePath, false);
|
||||
genFixedValue(gen, row, definition.getFixed(), snapshot, false, corePath, false);
|
||||
}
|
||||
if (isCoded(definition.getFixed()) && !hasDescription(definition.getFixed())) {
|
||||
Piece p = describeCoded(gen, definition.getFixed());
|
||||
|
@ -4722,7 +4727,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
} else if (definition.hasPattern()) {
|
||||
if (!c.getPieces().isEmpty()) { c.addPiece(gen.new Piece("br")); }
|
||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, translate("sd.table", "Required Pattern")+": ", null).addStyle("font-weight:bold")));
|
||||
if (!useTableForFixedValues || definition.getPattern().isPrimitive())
|
||||
if (!useTableForFixedValues || !allowSubRows || definition.getPattern().isPrimitive())
|
||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, buildJson(definition.getPattern()), null).addStyle("color: darkgreen")));
|
||||
else {
|
||||
c.getPieces().add(checkForNoChange(definition.getPattern(), gen.new Piece(null, "At least the following", null).addStyle("color: darkgreen")));
|
||||
|
@ -4762,6 +4767,13 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return c;
|
||||
}
|
||||
|
||||
private BindingResolution makeNullBr(ElementDefinitionBindingComponent binding) {
|
||||
BindingResolution br = new BindingResolution();
|
||||
br.url = "http://none.none/none";
|
||||
br.display = "todo";
|
||||
return br;
|
||||
}
|
||||
|
||||
private ElementDefinitionBindingComponent makeUnifiedBinding(ElementDefinitionBindingComponent binding, ElementDefinition element) {
|
||||
if (!element.hasUserData(DERIVATION_POINTER)) {
|
||||
return binding;
|
||||
|
@ -4802,7 +4814,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
ref = "?gen-fv?";
|
||||
}
|
||||
StructureDefinition sd = context.fetchTypeDefinition(value.fhirType());
|
||||
|
||||
|
||||
for (org.hl7.fhir.r5.model.Property t : value.children()) {
|
||||
if (t.getValues().size() > 0 || snapshot) {
|
||||
ElementDefinition ed = findElementDefinition(sd, t.getName());
|
||||
|
|
|
@ -1142,7 +1142,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
}
|
||||
CodeSystem cs = fetchResource(CodeSystem.class, inc.getSystem());
|
||||
if (cs != null) {
|
||||
if (cs != null && (cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == CodeSystemContentMode.FRAGMENT)) {
|
||||
pin.addParameter().setName("tx-resource").setResource(cs);
|
||||
if (isTxCaching && cacheId == null || !cached.contains(cs.getVUrl())) {
|
||||
cached.add(cs.getVUrl());
|
||||
|
|
|
@ -614,6 +614,9 @@ public class ExpressionNode {
|
|||
|
||||
public String check() {
|
||||
|
||||
if (kind == null) {
|
||||
return "Error in expression - node has no kind";
|
||||
}
|
||||
switch (kind) {
|
||||
case Name:
|
||||
if (Utilities.noString(name))
|
||||
|
|
|
@ -59,7 +59,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
p.addText(Utilities.capitalize(cm.getStatus().toString())+" (not intended for production usage). ");
|
||||
else
|
||||
p.addText(Utilities.capitalize(cm.getStatus().toString())+". ");
|
||||
p.tx("Published on "+(cm.hasDate() ? cm.getDateElement().toHumanDisplay() : "?ngen-10?")+" by "+cm.getPublisher());
|
||||
p.tx("Published on "+(cm.hasDate() ? display(cm.getDateElement()) : "?ngen-10?")+" by "+cm.getPublisher());
|
||||
if (!cm.getContact().isEmpty()) {
|
||||
p.tx(" (");
|
||||
boolean firsti = true;
|
||||
|
@ -132,11 +132,25 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
tr.td().b().tx("Destination Code");
|
||||
if (comment)
|
||||
tr.td().b().tx("Comment");
|
||||
tr = tbl.tr();
|
||||
XhtmlNode td = tr.td().colspan(comment ? "4" : "3");
|
||||
td.tx("Mapping from ");
|
||||
if (grp.hasSource()) {
|
||||
renderCanonical(cm, td, grp.getSource());
|
||||
} else {
|
||||
td.code("unspecified code system");
|
||||
}
|
||||
td.tx(" to ");
|
||||
if (grp.hasTarget()) {
|
||||
renderCanonical(cm, td, grp.getTarget());
|
||||
} else {
|
||||
td.code("unspecified code system");
|
||||
}
|
||||
for (SourceElementComponent ccl : grp.getElement()) {
|
||||
tr = tbl.tr();
|
||||
XhtmlNode td = tr.td();
|
||||
td = tr.td();
|
||||
td.addText(ccl.getCode());
|
||||
display = getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
|
||||
display = ccl.hasDisplay() ? ccl.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
|
||||
if (display != null && !isSameCodeAndDisplay(ccl.getCode(), display))
|
||||
td.tx(" ("+display+")");
|
||||
TargetElementComponent ccm = ccl.getTarget().get(0);
|
||||
|
@ -152,7 +166,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
}
|
||||
td = tr.td();
|
||||
td.addText(ccm.getCode());
|
||||
display = getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
|
||||
display = ccm.hasDisplay() ? ccm.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
|
||||
if (display != null && !isSameCodeAndDisplay(ccm.getCode(), display))
|
||||
td.tx(" ("+display+")");
|
||||
if (comment)
|
||||
|
|
|
@ -1139,9 +1139,11 @@ public class DataRenderer extends Renderer {
|
|||
protected String displayQuantity(Quantity q) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
|
||||
s.append("(system = '").append(TerminologyRenderer.describeSystem(q.getSystem()))
|
||||
.append("' code ").append(q.getCode())
|
||||
.append(" = '").append(lookupCode(q.getSystem(), null, q.getCode())).append("')");
|
||||
s.append(q.hasValue() ? q.getValue() : "?");
|
||||
if (q.hasUnit())
|
||||
s.append(" ").append(q.getUnit());
|
||||
else if (q.hasCode())
|
||||
s.append(" ").append(q.getCode());
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
@ -1158,26 +1160,33 @@ public class DataRenderer extends Renderer {
|
|||
}
|
||||
if (q.hasUnit())
|
||||
x.tx(" "+q.getUnit());
|
||||
else if (q.hasCode())
|
||||
x.tx(" "+q.getCode());
|
||||
else if (q.hasCode() && q.hasSystem()) {
|
||||
// if there's a code there *shall* be a system, so if we've got one and not the other, things are invalid and we won't bother trying to render
|
||||
if (q.hasSystem() && q.getSystem().equals("http://unitsofmeasure.org"))
|
||||
x.tx(" "+q.getCode());
|
||||
else
|
||||
x.tx("(unit "+q.getCode()+" from "+q.getSystem()+")");
|
||||
}
|
||||
if (showCodeDetails && q.hasCode()) {
|
||||
x.span("background: LightGoldenRodYellow", null).tx(" (Details: "+TerminologyRenderer.describeSystem(q.getSystem())+" code "+q.getCode()+" = '"+lookupCode(q.getSystem(), null, q.getCode())+"')");
|
||||
}
|
||||
}
|
||||
|
||||
public String displayRange(Range q) {
|
||||
if (!q.hasLow() && !q.hasHigh())
|
||||
return "?";
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
if (q.hasLow())
|
||||
b.append(q.getLow().getValue().toString());
|
||||
else
|
||||
b.append("?");
|
||||
b.append("-");
|
||||
if (q.hasHigh())
|
||||
b.append(q.getHigh().getValue().toString());
|
||||
else
|
||||
b.append("?");
|
||||
if (q.getLow().hasUnit())
|
||||
b.append(" "+q.getLow().getUnit());
|
||||
|
||||
boolean sameUnits = (q.getLow().hasUnit() && q.getHigh().hasUnit() && q.getLow().getUnit().equals(q.getHigh().getUnit()))
|
||||
|| (q.getLow().hasCode() && q.getHigh().hasCode() && q.getLow().getCode().equals(q.getHigh().getCode()));
|
||||
String low = "?";
|
||||
if (q.hasLow() && q.getLow().hasValue())
|
||||
low = sameUnits ? q.getLow().getValue().toString() : displayQuantity(q.getLow());
|
||||
String high = displayQuantity(q.getHigh());
|
||||
if (high.isEmpty())
|
||||
high = "?";
|
||||
b.append(low).append("\u00A0to\u00A0").append(high);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -158,9 +158,8 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
if (target.hasUserData("path")) {
|
||||
x.ah(target.getUserString("path")).tx(cr.present());
|
||||
} else {
|
||||
url = url.substring(0, url.indexOf("|"));
|
||||
x.code().tx(url);
|
||||
x.tx(": "+cr.present());
|
||||
x.tx(" ("+cr.present()+")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,7 +173,8 @@ public class ElementWrappers {
|
|||
s = s + " " + family.getValues().get(0).primitiveValue().toUpperCase();
|
||||
return s;
|
||||
} else {
|
||||
throw new Error("Now what? ("+b.fhirType()+")");
|
||||
// well, we couldn't get a name from that
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -142,6 +142,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||
}
|
||||
}
|
||||
}
|
||||
Coding foundCoding = null;
|
||||
if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
|
||||
Boolean result = false;
|
||||
for (Coding c : code.getCoding()) {
|
||||
|
@ -150,6 +151,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||
result = null;
|
||||
} else if (ok) {
|
||||
result = true;
|
||||
foundCoding = c;
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
|
@ -162,8 +164,10 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||
return new ValidationResult(IssueSeverity.ERROR, errors.toString());
|
||||
} else if (warnings.size() > 0) {
|
||||
return new ValidationResult(IssueSeverity.WARNING, warnings.toString());
|
||||
} else {
|
||||
return new ValidationResult(IssueSeverity.INFORMATION, null);
|
||||
} else {
|
||||
ConceptDefinitionComponent cd = new ConceptDefinitionComponent(foundCoding.getCode());
|
||||
cd.setDisplay(foundCoding.getDisplay());
|
||||
return new ValidationResult(foundCoding.getSystem(), cd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,6 +628,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||
break;
|
||||
}
|
||||
}
|
||||
i = valueset.getCompose().getInclude().size();
|
||||
for (ConceptSetComponent vsi : valueset.getCompose().getExclude()) {
|
||||
Boolean nok = inComponent(vsi, i, system, code, valueset.getCompose().getInclude().size() == 1, warnings);
|
||||
i++;
|
||||
|
|
|
@ -519,5 +519,8 @@ public class FHIRLexer {
|
|||
public int getCurrentStart() {
|
||||
return currentStart;
|
||||
}
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
}
|
|
@ -1000,7 +1000,9 @@ public class FHIRPathEngine {
|
|||
wrapper.setProximal(proximal);
|
||||
}
|
||||
|
||||
if (lexer.isConstant()) {
|
||||
if (lexer.getCurrent() == null) {
|
||||
throw lexer.error("Expression terminated unexpectedly");
|
||||
} else if (lexer.isConstant()) {
|
||||
boolean isString = lexer.isStringConstant();
|
||||
if (!isString && (lexer.getCurrent().startsWith("-") || lexer.getCurrent().startsWith("+"))) {
|
||||
// the grammar says that this is a unary operation; it affects the correct processing order of the inner operations
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This clas smaps between the jurisdictions defined for CanonicalResource.jurisdiction
|
||||
* and Java Locale
|
||||
* @author graha
|
||||
*
|
||||
*/
|
||||
|
||||
public class JurisdictionLocales {
|
||||
|
||||
private Map<String, String> map = new HashMap<>();
|
||||
|
||||
public JurisdictionLocales() {
|
||||
super();
|
||||
register();
|
||||
}
|
||||
|
||||
private void register() {
|
||||
register("USA", "US", "en-US");
|
||||
register("AUS", "AU", "en-AU");
|
||||
register("NZL", "NZ", "en-NZ");
|
||||
register("GBR", "GB", "en-GB");
|
||||
register("IND", "IN", "en-IN");
|
||||
|
||||
register("AUT", "AT", "de-AT");
|
||||
register("CHE", "CH", "de-CH");
|
||||
register("DEU", "DE", "de-DE");
|
||||
register("NOR", "NO", "no-NO");
|
||||
register("SWE", "SE", "sv-SE");
|
||||
register("FIN", "FI", "fi-FI");
|
||||
register("DNK", "DK", "da-DK");
|
||||
register("NLD", "NL", "nl-NL");
|
||||
register("BEL", "BE", "nl-BE"); // but will be fr-BE if lang is specified
|
||||
register("FRA", "FR", "fr-FR");
|
||||
register("ITA", "IT", "it-IT");
|
||||
register("RUS", "RU", "ru-RU");
|
||||
|
||||
register("ESP", "ES", "es-ES");
|
||||
register("ARG", "AR", "es-AR");
|
||||
register("UGY", "UY", "es-UY");
|
||||
|
||||
register("PRT", "PT", "pt-PT");
|
||||
register("BRA", "BR", "pt-BR");
|
||||
|
||||
register("CHN", "CN", "zh-CN");
|
||||
register("TWN", "TW", "zh-TW");
|
||||
register("JPN", "JP", "ja-JP");
|
||||
register("KOR", "KR", "ko-KR");
|
||||
register("VNM", "VN", "vn-VN");
|
||||
}
|
||||
|
||||
private void register(String code3, String code2, String locale) {
|
||||
map.put(code3, locale);
|
||||
map.put(code2, locale);
|
||||
}
|
||||
|
||||
public String get(String c) {
|
||||
return map.get(c.toUpperCase());
|
||||
}
|
||||
|
||||
}
|
|
@ -31,10 +31,13 @@ package org.hl7.fhir.r5.utils;
|
|||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleLinkComponent;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.ContactPoint;
|
||||
|
@ -61,6 +64,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
|||
public class ResourceUtilities {
|
||||
|
||||
public final static String FHIR_LANGUAGE = "urn:ietf:bcp:47";
|
||||
private static JurisdictionLocales jl = new JurisdictionLocales();
|
||||
|
||||
public static boolean isAnError(OperationOutcome error) {
|
||||
for (OperationOutcomeIssueComponent t : error.getIssue())
|
||||
|
@ -120,275 +124,40 @@ public class ResourceUtilities {
|
|||
resource.setMeta(new Meta());
|
||||
return resource.getMeta();
|
||||
}
|
||||
|
||||
// public static String representDataElementCollection(IWorkerContext context, Bundle bundle, boolean profileLink, String linkBase) {
|
||||
// StringBuilder b = new StringBuilder();
|
||||
// DataElement common = showDECHeader(b, bundle);
|
||||
// b.append("<table class=\"grid\">\r\n");
|
||||
// List<String> cols = chooseColumns(bundle, common, b, profileLink);
|
||||
// for (BundleEntryComponent e : bundle.getEntry()) {
|
||||
// DataElement de = (DataElement) e.getResource();
|
||||
// renderDE(de, cols, b, profileLink, linkBase);
|
||||
// }
|
||||
// b.append("</table>\r\n");
|
||||
// return b.toString();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private static void renderDE(DataElement de, List<String> cols, StringBuilder b, boolean profileLink, String linkBase) {
|
||||
// b.append("<tr>");
|
||||
// for (String col : cols) {
|
||||
// String v;
|
||||
// ElementDefinition dee = de.getElement().get(0);
|
||||
// if (col.equals("DataElement.name")) {
|
||||
// v = de.hasName() ? Utilities.escapeXml(de.getName()) : "";
|
||||
// } else if (col.equals("DataElement.status")) {
|
||||
// v = de.hasStatusElement() ? de.getStatusElement().asStringValue() : "";
|
||||
// } else if (col.equals("DataElement.code")) {
|
||||
// v = renderCoding(dee.getCode());
|
||||
// } else if (col.equals("DataElement.type")) {
|
||||
// v = dee.hasType() ? Utilities.escapeXml(dee.getType().get(0).getCode()) : "";
|
||||
// } else if (col.equals("DataElement.units")) {
|
||||
// v = renderDEUnits(ToolingExtensions.getAllowedUnits(dee));
|
||||
// } else if (col.equals("DataElement.binding")) {
|
||||
// v = renderBinding(dee.getBinding());
|
||||
// } else if (col.equals("DataElement.minValue")) {
|
||||
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/minValue") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/minValue").asStringValue()) : "";
|
||||
// } else if (col.equals("DataElement.maxValue")) {
|
||||
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/maxValue") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/maxValue").asStringValue()) : "";
|
||||
// } else if (col.equals("DataElement.maxLength")) {
|
||||
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/maxLength") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/maxLength").asStringValue()) : "";
|
||||
// } else if (col.equals("DataElement.mask")) {
|
||||
// v = ToolingExtensions.hasExtension(de, "http://hl7.org/fhir/StructureDefinition/mask") ? Utilities.escapeXml(ToolingExtensions.readPrimitiveExtension(de, "http://hl7.org/fhir/StructureDefinition/mask").asStringValue()) : "";
|
||||
// } else
|
||||
// throw new Error("Unknown column name: "+col);
|
||||
//
|
||||
// b.append("<td>"+v+"</td>");
|
||||
// }
|
||||
// if (profileLink) {
|
||||
// b.append("<td><a href=\""+linkBase+"-"+de.getId()+".html\">Profile</a>, <a href=\"http://www.opencem.org/#/20140917/Intermountain/"+de.getId()+"\">CEM</a>");
|
||||
// if (ToolingExtensions.hasExtension(de, ToolingExtensions.EXT_CIMI_REFERENCE))
|
||||
// b.append(", <a href=\""+ToolingExtensions.readStringExtension(de, ToolingExtensions.EXT_CIMI_REFERENCE)+"\">CIMI</a>");
|
||||
// b.append("</td>");
|
||||
// }
|
||||
// b.append("</tr>\r\n");
|
||||
// }
|
||||
|
||||
|
||||
|
||||
private static String renderBinding(ElementDefinitionBindingComponent binding) {
|
||||
// TODO Auto-generated method stub
|
||||
public static Locale getLocale(CanonicalResource cr) {
|
||||
return getLocale(cr.getLanguage(), cr.getJurisdiction());
|
||||
}
|
||||
|
||||
public static Locale getLocale(String lang, List<CodeableConcept> jurisdictions) {
|
||||
if (lang != null && lang.contains("-")) {
|
||||
return new Locale(lang);
|
||||
}
|
||||
for (CodeableConcept cc : jurisdictions) {
|
||||
Locale locale = getLocale(lang, cc);
|
||||
if (locale != null) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String renderDEUnits(DataType units) {
|
||||
if (units == null || units.isEmpty())
|
||||
return "";
|
||||
if (units instanceof CodeableConcept)
|
||||
return renderCodeable((CodeableConcept) units);
|
||||
else
|
||||
return "<a href=\""+Utilities.escapeXml(((Reference) units).getReference())+"\">"+Utilities.escapeXml(((Reference) units).getReference())+"</a>";
|
||||
|
||||
}
|
||||
|
||||
private static String renderCodeable(CodeableConcept units) {
|
||||
if (units == null || units.isEmpty())
|
||||
return "";
|
||||
String v = renderCoding(units.getCoding());
|
||||
if (units.hasText())
|
||||
v = v + " " +Utilities.escapeXml(units.getText());
|
||||
return v;
|
||||
}
|
||||
|
||||
private static String renderCoding(List<Coding> codes) {
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
for (Coding c : codes)
|
||||
b.append(renderCoding(c));
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private static String renderCoding(Coding code) {
|
||||
if (code == null || code.isEmpty())
|
||||
return "";
|
||||
else
|
||||
return "<span title=\""+Utilities.escapeXml(code.getSystem())+"\">"+Utilities.escapeXml(code.getCode())+"</span>";
|
||||
}
|
||||
|
||||
// private static List<String> chooseColumns(Bundle bundle, DataElement common, StringBuilder b, boolean profileLink) {
|
||||
// b.append("<tr>");
|
||||
// List<String> results = new ArrayList<String>();
|
||||
// results.add("DataElement.name");
|
||||
// b.append("<td width=\"250\"><b>Name</b></td>");
|
||||
// if (!common.hasStatus()) {
|
||||
// results.add("DataElement.status");
|
||||
// b.append("<td><b>Status</b></td>");
|
||||
// }
|
||||
// if (hasCode(bundle)) {
|
||||
// results.add("DataElement.code");
|
||||
// b.append("<td><b>Code</b></td>");
|
||||
// }
|
||||
// if (!common.getElement().get(0).hasType() && hasType(bundle)) {
|
||||
// results.add("DataElement.type");
|
||||
// b.append("<td><b>Type</b></td>");
|
||||
// }
|
||||
// if (hasUnits(bundle)) {
|
||||
// results.add("DataElement.units");
|
||||
// b.append("<td><b>Units</b></td>");
|
||||
// }
|
||||
// if (hasBinding(bundle)) {
|
||||
// results.add("DataElement.binding");
|
||||
// b.append("<td><b>Binding</b></td>");
|
||||
// }
|
||||
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/minValue")) {
|
||||
// results.add("DataElement.minValue");
|
||||
// b.append("<td><b>Min Value</b></td>");
|
||||
// }
|
||||
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/maxValue")) {
|
||||
// results.add("DataElement.maxValue");
|
||||
// b.append("<td><b>Max Value</b></td>");
|
||||
// }
|
||||
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/maxLength")) {
|
||||
// results.add("DataElement.maxLength");
|
||||
// b.append("<td><b>Max Length</b></td>");
|
||||
// }
|
||||
// if (hasExtension(bundle, "http://hl7.org/fhir/StructureDefinition/mask")) {
|
||||
// results.add("DataElement.mask");
|
||||
// b.append("<td><b>Mask</b></td>");
|
||||
// }
|
||||
// if (profileLink)
|
||||
// b.append("<td><b>Links</b></td>");
|
||||
// b.append("</tr>\r\n");
|
||||
// return results;
|
||||
// }
|
||||
//
|
||||
// private static boolean hasExtension(Bundle bundle, String url) {
|
||||
// for (BundleEntryComponent e : bundle.getEntry()) {
|
||||
// DataElement de = (DataElement) e.getResource();
|
||||
// if (ToolingExtensions.hasExtension(de, url))
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static boolean hasBinding(Bundle bundle) {
|
||||
// for (BundleEntryComponent e : bundle.getEntry()) {
|
||||
// DataElement de = (DataElement) e.getResource();
|
||||
// if (de.getElement().get(0).hasBinding())
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static boolean hasCode(Bundle bundle) {
|
||||
// for (BundleEntryComponent e : bundle.getEntry()) {
|
||||
// DataElement de = (DataElement) e.getResource();
|
||||
// if (de.getElement().get(0).hasCode())
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static boolean hasType(Bundle bundle) {
|
||||
// for (BundleEntryComponent e : bundle.getEntry()) {
|
||||
// DataElement de = (DataElement) e.getResource();
|
||||
// if (de.getElement().get(0).hasType())
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static boolean hasUnits(Bundle bundle) {
|
||||
// for (BundleEntryComponent e : bundle.getEntry()) {
|
||||
// DataElement de = (DataElement) e.getResource();
|
||||
// if (ToolingExtensions.getAllowedUnits(de.getElement().get(0)) != null)
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static DataElement showDECHeader(StringBuilder b, Bundle bundle) {
|
||||
// DataElement meta = new DataElement();
|
||||
// DataElement prototype = (DataElement) bundle.getEntry().get(0).getResource();
|
||||
// meta.setPublisher(prototype.getPublisher());
|
||||
// meta.getContact().addAll(prototype.getContact());
|
||||
// meta.setStatus(prototype.getStatus());
|
||||
// meta.setDate(prototype.getDate());
|
||||
// meta.addElement().getType().addAll(prototype.getElement().get(0).getType());
|
||||
//
|
||||
// for (BundleEntryComponent e : bundle.getEntry()) {
|
||||
// DataElement de = (DataElement) e.getResource();
|
||||
// if (!Base.compareDeep(de.getPublisherElement(), meta.getPublisherElement(), false))
|
||||
// meta.setPublisherElement(null);
|
||||
// if (!Base.compareDeep(de.getContact(), meta.getContact(), false))
|
||||
// meta.getContact().clear();
|
||||
// if (!Base.compareDeep(de.getStatusElement(), meta.getStatusElement(), false))
|
||||
// meta.setStatusElement(null);
|
||||
// if (!Base.compareDeep(de.getDateElement(), meta.getDateElement(), false))
|
||||
// meta.setDateElement(null);
|
||||
// if (!Base.compareDeep(de.getElement().get(0).getType(), meta.getElement().get(0).getType(), false))
|
||||
// meta.getElement().get(0).getType().clear();
|
||||
// }
|
||||
// if (meta.hasPublisher() || meta.hasContact() || meta.hasStatus() || meta.hasDate() /* || meta.hasType() */) {
|
||||
// b.append("<table class=\"grid\">\r\n");
|
||||
// if (meta.hasPublisher())
|
||||
// b.append("<tr><td>Publisher:</td><td>"+meta.getPublisher()+"</td></tr>\r\n");
|
||||
// if (meta.hasContact()) {
|
||||
// b.append("<tr><td>Contacts:</td><td>");
|
||||
// boolean firsti = true;
|
||||
// for (ContactDetail c : meta.getContact()) {
|
||||
// if (firsti)
|
||||
// firsti = false;
|
||||
// else
|
||||
// b.append("<br/>");
|
||||
// if (c.hasName())
|
||||
// b.append(Utilities.escapeXml(c.getName())+": ");
|
||||
// boolean first = true;
|
||||
// for (ContactPoint cp : c.getTelecom()) {
|
||||
// if (first)
|
||||
// first = false;
|
||||
// else
|
||||
// b.append(", ");
|
||||
// renderContactPoint(b, cp);
|
||||
// }
|
||||
// }
|
||||
// b.append("</td></tr>\r\n");
|
||||
// }
|
||||
// if (meta.hasStatus())
|
||||
// b.append("<tr><td>Status:</td><td>"+meta.getStatus().toString()+"</td></tr>\r\n");
|
||||
// if (meta.hasDate())
|
||||
// b.append("<tr><td>Date:</td><td>"+meta.getDateElement().asStringValue()+"</td></tr>\r\n");
|
||||
// if (meta.getElement().get(0).hasType())
|
||||
// b.append("<tr><td>Type:</td><td>"+renderType(meta.getElement().get(0).getType())+"</td></tr>\r\n");
|
||||
// b.append("</table>\r\n");
|
||||
// }
|
||||
// return meta;
|
||||
// }
|
||||
|
||||
private static String renderType(List<TypeRefComponent> type) {
|
||||
if (type == null || type.isEmpty())
|
||||
return "";
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
for (TypeRefComponent c : type)
|
||||
b.append(renderType(c));
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private static String renderType(TypeRefComponent type) {
|
||||
if (type == null || type.isEmpty())
|
||||
return "";
|
||||
return type.getWorkingCode();
|
||||
}
|
||||
|
||||
public static void renderContactPoint(StringBuilder b, ContactPoint cp) {
|
||||
if (cp != null && !cp.isEmpty()) {
|
||||
if (cp.getSystem() == ContactPointSystem.EMAIL)
|
||||
b.append("<a href=\"mailto:"+cp.getValue()+"\">"+cp.getValue()+"</a>");
|
||||
else if (cp.getSystem() == ContactPointSystem.FAX)
|
||||
b.append("Fax: "+cp.getValue());
|
||||
else if (cp.getSystem() == ContactPointSystem.OTHER)
|
||||
b.append("<a href=\""+cp.getValue()+"\">"+cp.getValue()+"</a>");
|
||||
else
|
||||
b.append(cp.getValue());
|
||||
private static Locale getLocale(String lang, CodeableConcept cc) {
|
||||
if (cc.hasCoding("http://unstats.un.org/unsd/methods/m49/m49.htm", "001")) {
|
||||
return new Locale("en-US");
|
||||
}
|
||||
}
|
||||
String c = cc.getCode("urn:iso:std:iso:3166");
|
||||
if (c == null) {
|
||||
return null;
|
||||
}
|
||||
String l = jl.get(c);
|
||||
if (l == null) {
|
||||
return null;
|
||||
} else if (lang != null) {
|
||||
return new Locale(lang+"-"+l.substring(l.indexOf("-")+1));
|
||||
} else {
|
||||
return new Locale(l);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -511,7 +511,7 @@ public class ToolingExtensions {
|
|||
* @return The extension, if on this element, else null
|
||||
*/
|
||||
public static Extension getExtension(DomainResource resource, String name) {
|
||||
if (name == null)
|
||||
if (resource == null || name == null)
|
||||
return null;
|
||||
if (!resource.hasExtension())
|
||||
return null;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.hl7.fhir.r5.utils.client.network;
|
||||
|
||||
import okhttp3.*;
|
||||
import okio.Buffer;
|
||||
|
||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -26,8 +28,17 @@ public class FhirLoggingInterceptor implements Interceptor {
|
|||
public Response intercept(@Nonnull Interceptor.Chain chain) throws IOException {
|
||||
// Log Request
|
||||
Request request = chain.request();
|
||||
logger.logRequest(request.method(), request.url().toString(), new ArrayList<>(request.headers().names()),
|
||||
request.body() != null ? request.body().toString().getBytes() : null);
|
||||
List<String> hdrs = new ArrayList<>();
|
||||
for (String s : request.headers().toString().split("\\n")) {
|
||||
hdrs.add(s.trim());
|
||||
}
|
||||
byte[] cnt = null;
|
||||
if (request.body() != null) {
|
||||
Buffer buf = new Buffer();
|
||||
request.body().writeTo(buf);
|
||||
cnt = buf.readByteArray();
|
||||
}
|
||||
logger.logRequest(request.method(), request.url().toString(), hdrs, cnt);
|
||||
|
||||
// Log Response
|
||||
Response response = null;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ public class SimpleHTTPClient {
|
|||
|
||||
public HTTPResult get(String url, String accept) throws IOException {
|
||||
URL u = new URL(url);
|
||||
boolean isSSL = url.startsWith("https://");
|
||||
// boolean isSSL = url.startsWith("https://");
|
||||
|
||||
// handling redirects - setInstanceFollowRedirects(true) doesn't handle crossing http to https
|
||||
|
||||
|
|
|
@ -649,7 +649,7 @@ public class Utilities {
|
|||
StringBuilder s = new StringBuilder();
|
||||
boolean d = false;
|
||||
for (String arg : args) {
|
||||
if (args != null) {
|
||||
if (arg != null) {
|
||||
if (!d)
|
||||
d = !noString(arg);
|
||||
else if (s.toString() != null && !s.toString().endsWith("/") && !arg.startsWith("/"))
|
||||
|
@ -660,14 +660,6 @@ public class Utilities {
|
|||
return s.toString();
|
||||
}
|
||||
|
||||
|
||||
// public static void checkCase(String filename) {
|
||||
// File f = new CSFile(filename);
|
||||
// if (!f.getName().equals(filename))
|
||||
// throw new FHIRException("Filename ")
|
||||
//
|
||||
// }
|
||||
|
||||
public static String nmtokenize(String cs) {
|
||||
if (cs == null)
|
||||
return "";
|
||||
|
|
|
@ -246,7 +246,7 @@ All_observations_should_have_a_performer = All observations should have a perfor
|
|||
All_observations_should_have_a_subject = All observations should have a subject
|
||||
Unable_to_resolve_slice_matching__no_fixed_value_or_required_value_set = Unable to resolve slice matching - no fixed value or required value set
|
||||
Unable_to_resolve_slice_matching__slice_matching_by_value_set_not_done = Unable to resolve slice matching - slice matching by value set not done
|
||||
Problem_processing_expression__in_profile__path__ = Problem processing expression {0} in profile {1} path {2}: {3}
|
||||
Problem_processing_expression__in_profile__path__ = Problem processing expression ''{0}'' in profile ''{1}'' at path ''{2}'': {3}
|
||||
Unable_to_find_element_with_id_ = Unable to find element with id ''{0}''
|
||||
Slice_encountered_midway_through_set_path___id___ = Slice encountered midway through set (path = {0}, id = {1}); {2}
|
||||
Unable_to_resolve_actual_type_ = Unable to resolve actual type {0}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -54,6 +54,10 @@
|
|||
<artifactId>okhttp</artifactId>
|
||||
<version>4.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atlassian.commonmark</groupId>
|
||||
<artifactId>commonmark</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -167,6 +167,13 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.atlassian.commonmark</groupId>
|
||||
<artifactId>commonmark</artifactId>
|
||||
<optional>true</optional>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.javalin</groupId>
|
||||
<artifactId>javalin</artifactId>
|
||||
|
|
|
@ -4656,7 +4656,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
timeTracker.sd(t);
|
||||
trackUsage(profile, hostContext, element);
|
||||
if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(),
|
||||
profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_TYPE, special.toHuman(), resourceName)) {
|
||||
profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_TYPE, special == null ? "??" : special.toHuman(), resourceName)) {
|
||||
validateResource(hc, errors, resource, element, profile, idstatus, stack);
|
||||
}
|
||||
} else {
|
||||
|
@ -5490,7 +5490,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
try {
|
||||
n = fpe.parse(fixExpr(inv.getExpression(), inv.getKey()));
|
||||
} catch (FHIRLexerException e) {
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, inv.getExpression(), profile.getUrl(), path, e.getMessage()));
|
||||
rule(errors, IssueType.INVARIANT, element.line(), element.col(), path, false, I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, inv.getExpression(), profile.getUrl(), path, e.getMessage());
|
||||
return;
|
||||
}
|
||||
timeTracker.fpe(t);
|
||||
inv.setUserData("validator.expression.cache", n);
|
||||
|
|
7
pom.xml
7
pom.xml
|
@ -14,12 +14,12 @@
|
|||
HAPI FHIR
|
||||
-->
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.6.22-SNAPSHOT</version>
|
||||
<version>5.6.24-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.1.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.84-SNAPSHOT</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.87</validator_test_case_version>
|
||||
<junit_jupiter_version>5.7.1</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.7.1</junit_platform_launcher_version>
|
||||
<maven_surefire_version>3.0.0-M5</maven_surefire_version>
|
||||
|
@ -397,6 +397,9 @@
|
|||
Surefire testing run. This may appear as an error in some IDEs, but it will run regardless.
|
||||
-->
|
||||
<argLine>${argLine} -Xmx4096m</argLine>
|
||||
<systemPropertyVariables>
|
||||
<java.locale.providers>COMPAT</java.locale.providers>
|
||||
</systemPropertyVariables>
|
||||
<redirectTestOutputToFile>false</redirectTestOutputToFile>
|
||||
<excludes>
|
||||
<exclude>org/hl7/fhir/validation/cli/**</exclude>
|
||||
|
|
Loading…
Reference in New Issue