version comparison support (#284)
* add package url fixer * fix problems doing CCDA snapshots * Fix for http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation * improve error message * fix package id in generated version specific tests * remove spurious debug statement * rework package loaders for automatic loading of package dependencies * fix spelling mistake * add automatic loading of package dependencies by the context * significant work on tests to support version comparison * fix minor loading issue * compile fix * utils support * fixes for version comparison * rework error handling when expanding valuesets + add error check on value set imports * fix loading bug * improve error message
This commit is contained in:
parent
b9755c8f1f
commit
bf0f81f51b
|
@ -0,0 +1,84 @@
|
|||
package org.hl7.fhir.convertors.loaders;
|
||||
|
||||
import org.hl7.fhir.dstu3.context.SimpleWorkerContext.IContextResourceLoader;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.ElementDefinition;
|
||||
import org.hl7.fhir.dstu3.model.Resource;
|
||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseLoaderR3 implements IContextResourceLoader {
|
||||
|
||||
public interface ILoaderKnowledgeProvider {
|
||||
/**
|
||||
* get the path for references to this resource.
|
||||
* @param resource
|
||||
* @return null if not tracking paths
|
||||
*/
|
||||
String getResourcePath(Resource resource);
|
||||
}
|
||||
|
||||
public static class NullLoaderKnowledgeProvider implements ILoaderKnowledgeProvider {
|
||||
@Override
|
||||
public String getResourcePath(Resource resource) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
protected final String URL_BASE = "http://hl7.org/fhir/";
|
||||
protected final String URL_DSTU2 = "http://hl7.org/fhir/1.0/";
|
||||
protected final String URL_DSTU2016MAY = "http://hl7.org/fhir/1.4/";
|
||||
protected final String URL_DSTU3 = "http://hl7.org/fhir/3.0/";
|
||||
protected final String URL_R4 = "http://hl7.org/fhir/4.0/";
|
||||
|
||||
protected final String URL_ELEMENT_DEF_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
|
||||
|
||||
protected boolean patchUrls;
|
||||
protected boolean killPrimitives;;
|
||||
|
||||
private String[] types;
|
||||
private ILoaderKnowledgeProvider lkp;
|
||||
|
||||
public BaseLoaderR3(String[] types, ILoaderKnowledgeProvider lkp) {
|
||||
super();
|
||||
this.types = types;
|
||||
this.lkp = lkp;
|
||||
}
|
||||
|
||||
public String[] getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public boolean isPatchUrls() {
|
||||
return patchUrls;
|
||||
}
|
||||
|
||||
public BaseLoaderR3 setPatchUrls(boolean patchUrls) {
|
||||
this.patchUrls = patchUrls;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isKillPrimitives() {
|
||||
return killPrimitives;
|
||||
}
|
||||
|
||||
public BaseLoaderR3 setKillPrimitives(boolean killPrimitives) {
|
||||
this.killPrimitives = killPrimitives;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getResourcePath(Resource resource) {
|
||||
return lkp.getResourcePath(resource);
|
||||
}
|
||||
|
||||
public void setPath(Resource r) {
|
||||
String path = lkp.getResourcePath(r);
|
||||
if (path != null) {
|
||||
r.setUserData("path", path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package org.hl7.fhir.convertors.loaders;
|
||||
|
||||
import org.hl7.fhir.r4.context.SimpleWorkerContext.IContextResourceLoader;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.CanonicalType;
|
||||
import org.hl7.fhir.r4.model.ElementDefinition;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseLoaderR4 implements IContextResourceLoader {
|
||||
|
||||
public interface ILoaderKnowledgeProvider {
|
||||
/**
|
||||
* get the path for references to this resource.
|
||||
* @param resource
|
||||
* @return null if not tracking paths
|
||||
*/
|
||||
String getResourcePath(Resource resource);
|
||||
}
|
||||
|
||||
public static class NullLoaderKnowledgeProvider implements ILoaderKnowledgeProvider {
|
||||
@Override
|
||||
public String getResourcePath(Resource resource) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
protected final String URL_BASE = "http://hl7.org/fhir/";
|
||||
protected final String URL_DSTU2 = "http://hl7.org/fhir/1.0/";
|
||||
protected final String URL_DSTU2016MAY = "http://hl7.org/fhir/1.4/";
|
||||
protected final String URL_DSTU3 = "http://hl7.org/fhir/3.0/";
|
||||
protected final String URL_R4 = "http://hl7.org/fhir/4.0/";
|
||||
|
||||
protected final String URL_ELEMENT_DEF_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
|
||||
|
||||
protected boolean patchUrls;
|
||||
protected boolean killPrimitives;;
|
||||
|
||||
private String[] types;
|
||||
private ILoaderKnowledgeProvider lkp;
|
||||
|
||||
public BaseLoaderR4(String[] types, ILoaderKnowledgeProvider lkp) {
|
||||
super();
|
||||
this.types = types;
|
||||
this.lkp = lkp;
|
||||
}
|
||||
|
||||
public String[] getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public boolean isPatchUrls() {
|
||||
return patchUrls;
|
||||
}
|
||||
|
||||
public BaseLoaderR4 setPatchUrls(boolean patchUrls) {
|
||||
this.patchUrls = patchUrls;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isKillPrimitives() {
|
||||
return killPrimitives;
|
||||
}
|
||||
|
||||
public BaseLoaderR4 setKillPrimitives(boolean killPrimitives) {
|
||||
this.killPrimitives = killPrimitives;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getResourcePath(Resource resource) {
|
||||
return lkp.getResourcePath(resource);
|
||||
}
|
||||
|
||||
public void setPath(Resource r) {
|
||||
String path = lkp.getResourcePath(r);
|
||||
if (path != null) {
|
||||
r.setUserData("path", path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,16 +1,22 @@
|
|||
package org.hl7.fhir.convertors.loaders;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseLoaderR5 {
|
||||
public abstract class BaseLoaderR5 implements IContextResourceLoader {
|
||||
|
||||
public interface ILoaderKnowledgeProvider {
|
||||
/**
|
||||
|
@ -19,6 +25,7 @@ public abstract class BaseLoaderR5 {
|
|||
* @return null if not tracking paths
|
||||
*/
|
||||
String getResourcePath(Resource resource);
|
||||
ILoaderKnowledgeProvider forNewPackage(NpmPackage npm) throws JsonSyntaxException, IOException;
|
||||
}
|
||||
|
||||
public static class NullLoaderKnowledgeProvider implements ILoaderKnowledgeProvider {
|
||||
|
@ -26,6 +33,11 @@ public abstract class BaseLoaderR5 {
|
|||
public String getResourcePath(Resource resource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILoaderKnowledgeProvider forNewPackage(NpmPackage npm) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
protected final String URL_BASE = "http://hl7.org/fhir/";
|
||||
protected final String URL_DSTU2 = "http://hl7.org/fhir/1.0/";
|
||||
|
@ -38,8 +50,8 @@ public abstract class BaseLoaderR5 {
|
|||
protected boolean patchUrls;
|
||||
protected boolean killPrimitives;;
|
||||
|
||||
private String[] types;
|
||||
private ILoaderKnowledgeProvider lkp;
|
||||
protected String[] types;
|
||||
protected ILoaderKnowledgeProvider lkp;
|
||||
|
||||
public BaseLoaderR5(String[] types, ILoaderKnowledgeProvider lkp) {
|
||||
super();
|
||||
|
@ -80,4 +92,28 @@ public abstract class BaseLoaderR5 {
|
|||
}
|
||||
}
|
||||
|
||||
public IContextResourceLoader getNewLoader(NpmPackage npm) throws JsonSyntaxException, IOException {
|
||||
BaseLoaderR5 ret = loaderFactory(npm);
|
||||
ret.patchUrls = patchUrls;
|
||||
ret.killPrimitives = killPrimitives;
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected BaseLoaderR5 loaderFactory(NpmPackage npm) throws JsonSyntaxException, IOException {
|
||||
if (VersionUtilities.isR5Ver(npm.fhirVersion())) {
|
||||
return new R5ToR5Loader(types, lkp.forNewPackage(npm));
|
||||
} else if (VersionUtilities.isR4Ver(npm.fhirVersion())) {
|
||||
return new R4ToR5Loader(types, lkp.forNewPackage(npm));
|
||||
} else if (VersionUtilities.isR3Ver(npm.fhirVersion())) {
|
||||
return new R3ToR5Loader(types, lkp.forNewPackage(npm));
|
||||
} else if (VersionUtilities.isR2Ver(npm.fhirVersion())) {
|
||||
return new R2ToR5Loader(types, lkp.forNewPackage(npm));
|
||||
} else if (VersionUtilities.isR2BVer(npm.fhirVersion())) {
|
||||
return new R2016MayToR5Loader(types, lkp.forNewPackage(npm));
|
||||
} else {
|
||||
throw new FHIRException("Unsupported FHIR Version "+npm.fhirVersion());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -55,7 +55,7 @@ import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind;
|
|||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
|
||||
public class R2016MayToR4Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor40 {
|
||||
public class R2016MayToR4Loader extends BaseLoaderR4 implements IContextResourceLoader, VersionConvertorAdvisor40 {
|
||||
|
||||
private List<CodeSystem> cslist = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -57,8 +57,11 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
public class R2016MayToR5Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor50 {
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
public class R2016MayToR5Loader extends BaseLoaderR5 implements VersionConvertorAdvisor50 {
|
||||
|
||||
public R2016MayToR5Loader(String[] types, ILoaderKnowledgeProvider lkp) {
|
||||
super(types, lkp);
|
||||
|
@ -193,4 +196,6 @@ public class R2016MayToR5Loader extends BaseLoaderR5 implements IContextResource
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -54,7 +54,7 @@ import org.hl7.fhir.dstu3.model.UriType;
|
|||
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
public class R2ToR3Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor30 {
|
||||
public class R2ToR3Loader extends BaseLoaderR3 implements VersionConvertorAdvisor30 {
|
||||
|
||||
private List<CodeSystem> cslist = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind;
|
|||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
|
||||
public class R2ToR4Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor40 {
|
||||
public class R2ToR4Loader extends BaseLoaderR4 implements VersionConvertorAdvisor40 {
|
||||
|
||||
private List<CodeSystem> cslist = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
public class R2ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor50 {
|
||||
|
||||
|
@ -192,4 +195,5 @@ public class R2ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -51,7 +51,7 @@ import org.hl7.fhir.r4.model.Bundle.BundleType;
|
|||
import org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind;
|
||||
|
||||
public class R3ToR4Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor40 {
|
||||
public class R3ToR4Loader extends BaseLoaderR4 implements IContextResourceLoader, VersionConvertorAdvisor40 {
|
||||
|
||||
private List<CodeSystem> cslist = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
public class R3ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor50 {
|
||||
|
||||
|
@ -195,4 +198,5 @@ public class R3ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader
|
|||
public org.hl7.fhir.r4.model.Resource convertR4(org.hl7.fhir.r5.model.Resource resource) throws FHIRException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -58,6 +58,9 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
public class R4ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor50 {
|
||||
|
||||
|
|
|
@ -57,8 +57,11 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
|
||||
public class R5ToR5Loader extends BaseLoaderR5 implements IContextResourceLoader, VersionConvertorAdvisor50 {
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
public class R5ToR5Loader extends BaseLoaderR5 implements VersionConvertorAdvisor50 {
|
||||
|
||||
public R5ToR5Loader(String[] types, ILoaderKnowledgeProvider lkp) {
|
||||
super(types, lkp);
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.hl7.fhir.utilities.TextFile;
|
|||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackageIndexBuilder;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage.NpmPackageFolder;
|
||||
import org.hl7.fhir.utilities.json.JSONUtil;
|
||||
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
@ -217,6 +218,9 @@ public class NpmPackageVersionConverter {
|
|||
private byte[] convertPackage(byte[] cnt) throws IOException {
|
||||
JsonObject json = JsonTrackingParser.parseJson(cnt);
|
||||
currentVersion = json.getAsJsonArray("fhirVersions").get(0).getAsString();
|
||||
String name = JSONUtil.str(json, "name");
|
||||
json.remove("name");
|
||||
json.addProperty("name", name+"."+vCode);
|
||||
json.remove("fhirVersions");
|
||||
json.remove("dependencies");
|
||||
JsonArray fv = new JsonArray();
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
@ -81,6 +82,28 @@ public abstract class CanonicalResourceComparer extends ResourceComparer {
|
|||
this.intersection = intersection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toTable() {
|
||||
String s = null;
|
||||
if (left != null && right != null && !left.getUrl().equals(right.getUrl())) {
|
||||
s = "<td>"+left.getUrl()+"</td><td>"+right.getUrl()+"</td>";
|
||||
} else if (left != null) {
|
||||
s = "<td colspan=2>"+left.getUrl()+"</td>";
|
||||
} else {
|
||||
s = "<td colspan=2>"+right.getUrl()+"</td>";
|
||||
}
|
||||
s = s + "<td><a href=\""+getId()+".html\">Comparison</a></td>";
|
||||
s = s + "<td>"+outcomeSummary()+"</td>";
|
||||
return "<tr style=\"background-color: "+color()+"\">"+s+"</tr>\r\n";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void countMessages(MessageCounts cnts) {
|
||||
for (StructuralMatch<String> sm : metadata.values()) {
|
||||
sm.countMessages(cnts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CanonicalResourceComparer(ComparisonSession session) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
|||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent;
|
||||
|
@ -55,6 +56,18 @@ public class CodeSystemComparer extends CanonicalResourceComparer {
|
|||
protected String summary() {
|
||||
return "CodeSystem: "+left.present()+" vs "+right.present();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String fhirType() {
|
||||
return "CodeSystem";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void countMessages(MessageCounts cnts) {
|
||||
super.countMessages(cnts);
|
||||
combined.countMessages(cnts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CodeSystem right;
|
||||
|
|
|
@ -2,6 +2,8 @@ package org.hl7.fhir.r5.comparison;
|
|||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -13,6 +15,7 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.PlaceHolderComparison;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||
|
||||
|
@ -35,14 +38,16 @@ import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
|||
|
||||
public class ComparisonRenderer implements IEvaluationContext {
|
||||
|
||||
private IWorkerContext context;
|
||||
private IWorkerContext contextLeft;
|
||||
private IWorkerContext contextRight;
|
||||
private ComparisonSession session;
|
||||
private Map<String, String> templates = new HashMap<>();
|
||||
private String folder;
|
||||
|
||||
public ComparisonRenderer(IWorkerContext context, String folder, ComparisonSession session) {
|
||||
public ComparisonRenderer(IWorkerContext contextLeft, IWorkerContext contextRight, String folder, ComparisonSession session) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.contextLeft = contextLeft;
|
||||
this.contextRight = contextRight;
|
||||
this.folder = folder;
|
||||
this.session = session;
|
||||
}
|
||||
|
@ -54,12 +59,13 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
public void render() throws IOException {
|
||||
dumpBinaries();
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
for (String id : sorted(session.getCompares().keySet())) {
|
||||
ResourceComparison comp = session.getCompares().get(id);
|
||||
renderComparison(id, comp);
|
||||
b.append("<li><a href=\""+comp.getId()+".html\">"+Utilities.escapeXml(comp.summary())+"</a></li>\r\n");
|
||||
}
|
||||
b.append("<table class=\"grid\">\r\n");
|
||||
List<String> list = sorted(session.getCompares().keySet());
|
||||
processList(list, b, "CodeSystem");
|
||||
processList(list, b, "ValueSet");
|
||||
processList(list, b, "StructureDefinition");
|
||||
b.append("</table>\r\n");
|
||||
|
||||
Map<String, Base> vars = new HashMap<>();
|
||||
CodeSystemComparer cs = new CodeSystemComparer(session);
|
||||
vars.put("title", new StringType(session.getTitle()));
|
||||
|
@ -69,6 +75,23 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
TextFile.stringToFile(cnt, file("index.html"));
|
||||
}
|
||||
|
||||
private void processList(List<String> list, StringBuilder b, String name) throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
boolean first = true;
|
||||
for (String id : list) {
|
||||
ResourceComparison comp = session.getCompares().get(id);
|
||||
if (comp.fhirType().equals(name)) {
|
||||
if (first) {
|
||||
first = false;
|
||||
b.append("<tr><td colspan=4><b>"+name+"</b></td></tr>\r\n");
|
||||
}
|
||||
renderComparison(id, comp);
|
||||
b.append(comp.toTable());
|
||||
//"<li><a href=\""+comp.getId()+".html\">"+Utilities.escapeXml(comp.summary())+"</a></li>\r\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> sorted(Set<String> keySet) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.addAll(keySet);
|
||||
|
@ -77,8 +100,11 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
}
|
||||
|
||||
private void dumpBinaries() throws IOException {
|
||||
for (String k : context.getBinaries().keySet()) {
|
||||
TextFile.bytesToFile(context.getBinaries().get(k), Utilities.path(folder, k));
|
||||
for (String k : contextLeft.getBinaries().keySet()) {
|
||||
TextFile.bytesToFile(contextLeft.getBinaries().get(k), Utilities.path(folder, k));
|
||||
}
|
||||
for (String k : contextRight.getBinaries().keySet()) {
|
||||
TextFile.bytesToFile(contextRight.getBinaries().get(k), Utilities.path(folder, k));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,9 +115,23 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
renderValueSet(id, (ValueSetComparison) comp);
|
||||
} else if (comp instanceof CodeSystemComparison) {
|
||||
renderCodeSystem(id, (CodeSystemComparison) comp);
|
||||
} else if (comp instanceof PlaceHolderComparison) {
|
||||
renderPlaceHolder(id, (PlaceHolderComparison) comp);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderPlaceHolder(String id, PlaceHolderComparison comp) throws IOException {
|
||||
String cnt = "";
|
||||
if (comp.getE() != null) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
comp.getE().printStackTrace(pw);
|
||||
cnt = sw.toString();
|
||||
}
|
||||
cnt = "<html><body><pre>"+cnt+"</pre></body></html>\r\n";
|
||||
TextFile.stringToFile(cnt, file(comp.getId()+".html"));
|
||||
}
|
||||
|
||||
private void renderCodeSystem(String id, CodeSystemComparison comp) throws IOException {
|
||||
String template = templates.get("CodeSystem");
|
||||
Map<String, Base> vars = new HashMap<>();
|
||||
|
@ -138,7 +178,7 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
private void renderProfile(String id, ProfileComparison comp) throws IOException {
|
||||
String template = templates.get("Profile");
|
||||
Map<String, Base> vars = new HashMap<>();
|
||||
ProfileComparer cs = new ProfileComparer(session, new ProfileUtilities(session.getContext(), null, session.getPkp()));
|
||||
ProfileComparer cs = new ProfileComparer(session, new ProfileUtilities(session.getContextLeft(), null, session.getPkp()), new ProfileUtilities(session.getContextRight(), null, session.getPkp()));
|
||||
vars.put("left", new StringType(comp.getLeft().present()));
|
||||
vars.put("right", new StringType(comp.getRight().present()));
|
||||
vars.put("leftId", new StringType(comp.getLeft().getId()));
|
||||
|
@ -155,7 +195,7 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
}
|
||||
|
||||
private String processTemplate(String template, String name, Map<String, Base> vars) {
|
||||
LiquidEngine engine = new LiquidEngine(context, this);
|
||||
LiquidEngine engine = new LiquidEngine(contextRight, this);
|
||||
LiquidDocument doc = engine.parse(template, name+".template");
|
||||
return engine.evaluate(doc, Tuple.fromMap(vars), vars);
|
||||
}
|
||||
|
|
|
@ -25,24 +25,30 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
public class ComparisonSession {
|
||||
|
||||
private Map<String, ResourceComparison> compares = new HashMap<>();
|
||||
private IWorkerContext context;
|
||||
private IWorkerContext contextLeft;
|
||||
private IWorkerContext contextRight;
|
||||
private String sessiondId;
|
||||
private int count;
|
||||
private boolean debug;
|
||||
private String title;
|
||||
private ProfileKnowledgeProvider pkp;
|
||||
|
||||
public ComparisonSession(IWorkerContext context, String title, ProfileKnowledgeProvider pkp) {
|
||||
public ComparisonSession(IWorkerContext contextLeft, IWorkerContext contextRight, String title, ProfileKnowledgeProvider pkp) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.contextLeft = contextLeft;
|
||||
this.contextRight = contextRight;
|
||||
this.sessiondId = UUID.randomUUID().toString().toLowerCase();
|
||||
this.title = title;
|
||||
this.pkp = pkp;
|
||||
// debug = true;
|
||||
}
|
||||
|
||||
public IWorkerContext getContext() {
|
||||
return context;
|
||||
public IWorkerContext getContextLeft() {
|
||||
return contextLeft;
|
||||
}
|
||||
|
||||
public IWorkerContext getContextRight() {
|
||||
return contextRight;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
|
@ -50,11 +56,11 @@ public class ComparisonSession {
|
|||
}
|
||||
|
||||
public ResourceComparison compare(String left, String right) throws DefinitionException, FHIRFormatError, IOException {
|
||||
CanonicalResource l = (CanonicalResource) context.fetchResource(Resource.class, left);
|
||||
CanonicalResource l = (CanonicalResource) contextLeft.fetchResource(Resource.class, left);
|
||||
if (l == null) {
|
||||
throw new DefinitionException("Unable to resolve "+left);
|
||||
}
|
||||
CanonicalResource r = (CanonicalResource) context.fetchResource(Resource.class, right);
|
||||
CanonicalResource r = (CanonicalResource) contextRight.fetchResource(Resource.class, right);
|
||||
if (r == null) {
|
||||
throw new DefinitionException("Unable to resolve "+right);
|
||||
}
|
||||
|
@ -62,30 +68,54 @@ public class ComparisonSession {
|
|||
}
|
||||
|
||||
public ResourceComparison compare(CanonicalResource left, CanonicalResource right) throws DefinitionException, FHIRFormatError, IOException {
|
||||
String key = key(left.getUrl(), left.getVersion(), right.getUrl(), right.getVersion());
|
||||
if (compares.containsKey(key)) {
|
||||
// if null then the comparison is in progress.
|
||||
// this can happen when profiles refer to each other
|
||||
return compares.get(key);
|
||||
}
|
||||
compares.put(key, null);
|
||||
if (left instanceof CodeSystem && right instanceof CodeSystem) {
|
||||
CodeSystemComparer cs = new CodeSystemComparer(this);
|
||||
CodeSystemComparison csc = cs.compare((CodeSystem) left, (CodeSystem) right);
|
||||
if (left != null && right != null) {
|
||||
String key = key(left.getUrl(), left.getVersion(), right.getUrl(), right.getVersion());
|
||||
if (compares.containsKey(key)) {
|
||||
// if null then the comparison is in progress.
|
||||
// this can happen when profiles refer to each other
|
||||
return compares.get(key);
|
||||
}
|
||||
compares.put(key, null);
|
||||
try {
|
||||
if (left instanceof CodeSystem && right instanceof CodeSystem) {
|
||||
CodeSystemComparer cs = new CodeSystemComparer(this);
|
||||
CodeSystemComparison csc = cs.compare((CodeSystem) left, (CodeSystem) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else if (left instanceof ValueSet && right instanceof ValueSet) {
|
||||
ValueSetComparer cs = new ValueSetComparer(this);
|
||||
ValueSetComparison csc = cs.compare((ValueSet) left, (ValueSet) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
|
||||
ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(contextLeft, null, pkp), new ProfileUtilities(contextRight, null, pkp));
|
||||
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else {
|
||||
throw new FHIRException("Unable to compare resources of type "+left.fhirType()+" and "+right.fhirType());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right, e);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
}
|
||||
} else if (left != null) {
|
||||
String key = key(left.getUrl(), left.getVersion(), left.getUrl(), left.getVersion());
|
||||
if (compares.containsKey(key)) {
|
||||
return compares.get(key);
|
||||
}
|
||||
ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else if (left instanceof ValueSet && right instanceof ValueSet) {
|
||||
ValueSetComparer cs = new ValueSetComparer(this);
|
||||
ValueSetComparison csc = cs.compare((ValueSet) left, (ValueSet) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
|
||||
ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(context, null, pkp));
|
||||
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
return csc;
|
||||
} else {
|
||||
throw new FHIRException("Unable to compare ");
|
||||
String key = key(right.getUrl(), right.getVersion(), right.getUrl(), right.getVersion());
|
||||
if (compares.containsKey(key)) {
|
||||
return compares.get(key);
|
||||
}
|
||||
ResourceComparer.PlaceHolderComparison csc = new ResourceComparer.PlaceHolderComparison(left, right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,11 @@ import java.util.List;
|
|||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.UnusedTracker;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.formats.IParser;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
|
@ -63,16 +65,29 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
protected String summary() {
|
||||
return "Profile: "+left.present()+" vs "+right.present();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String fhirType() {
|
||||
return "StructureDefinition";
|
||||
}
|
||||
@Override
|
||||
protected void countMessages(MessageCounts cnts) {
|
||||
super.countMessages(cnts);
|
||||
combined.countMessages(cnts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private ProfileUtilities utils;
|
||||
private ProfileUtilities utilsLeft;
|
||||
private ProfileUtilities utilsRight;
|
||||
|
||||
public ProfileComparer(ComparisonSession session, ProfileUtilities utils) {
|
||||
public ProfileComparer(ComparisonSession session, ProfileUtilities utilsLeft, ProfileUtilities utilsRight) {
|
||||
super(session);
|
||||
this.utils = utils;
|
||||
this.utilsLeft = utilsLeft;
|
||||
this.utilsRight = utilsRight;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,8 +125,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
comparePrimitives("baseDefinition", left.getBaseDefinitionElement(), right.getBaseDefinitionElement(), res.getMetadata(), IssueSeverity.ERROR, res);
|
||||
|
||||
if (left.getType().equals(right.getType())) {
|
||||
DefinitionNavigator ln = new DefinitionNavigator(session.getContext(), left);
|
||||
DefinitionNavigator rn = new DefinitionNavigator(session.getContext(), right);
|
||||
DefinitionNavigator ln = new DefinitionNavigator(session.getContextLeft(), left);
|
||||
DefinitionNavigator rn = new DefinitionNavigator(session.getContextRight(), right);
|
||||
StructuralMatch<ElementDefinition> sm = new StructuralMatch<ElementDefinition>(ln.current(), rn.current());
|
||||
compareElements(res, sm, ln.path(), null, ln, rn);
|
||||
res.combined = sm;
|
||||
|
@ -122,9 +137,9 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
private void check(StructureDefinition sd, String name) {
|
||||
if (sd == null)
|
||||
throw new DefinitionException("No StructureDefinition provided ("+name+": "+sd.getName()+")");
|
||||
if (sd.getType().equals("Extension")) {
|
||||
throw new DefinitionException("StructureDefinition is for an extension - use ExtensionComparer instead ("+name+": "+sd.getName()+")");
|
||||
}
|
||||
// if (sd.getType().equals("Extension")) {
|
||||
// throw new DefinitionException("StructureDefinition is for an extension - use ExtensionComparer instead ("+name+": "+sd.getName()+")");
|
||||
// }
|
||||
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||
throw new DefinitionException("StructureDefinition is not for an profile - can't be compared ("+name+": "+sd.getName()+")");
|
||||
}
|
||||
|
@ -143,10 +158,10 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
}
|
||||
|
||||
// not allowed to be different:
|
||||
ruleEqual(comp, res, left.current().getDefaultValue(), right.current().getDefaultValue(), "defaultValue", path);
|
||||
ruleEqual(comp, res, left.current().getMeaningWhenMissingElement(), right.current().getMeaningWhenMissingElement(), "meaningWhenMissing", path);
|
||||
ruleEqual(comp, res, left.current().getIsModifierElement(), right.current().getIsModifierElement(), "isModifier", path);
|
||||
ruleEqual(comp, res, left.current().getIsSummaryElement(), right.current().getIsSummaryElement(), "isSummary", path);
|
||||
// ruleEqual(comp, res, left.current().getDefaultValue(), right.current().getDefaultValue(), "defaultValue", path);
|
||||
// ruleEqual(comp, res, left.current().getMeaningWhenMissingElement(), right.current().getMeaningWhenMissingElement(), "meaningWhenMissing", path);
|
||||
// ruleEqual(comp, res, left.current().getIsModifierElement(), right.current().getIsModifierElement(), "isModifier", path); - this check belongs in the core
|
||||
// ruleEqual(comp, res, left.current().getIsSummaryElement(), right.current().getIsSummaryElement(), "isSummary", path); - so does this
|
||||
|
||||
// we ignore slicing right now - we're going to clone the root one anyway, and then think about clones
|
||||
// simple stuff
|
||||
|
@ -317,15 +332,15 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
} else if (vRight == null) {
|
||||
vm(IssueSeverity.ERROR, "Removed "+name, path, comp.getMessages(), res.getMessages());
|
||||
} else if (!Base.compareDeep(vLeft, vRight, false)) {
|
||||
vm(IssueSeverity.ERROR, name+" must be the same ("+toString(vLeft)+"/"+toString(vRight)+")", path, comp.getMessages(), res.getMessages());
|
||||
vm(IssueSeverity.ERROR, name+" must be the same ("+toString(vLeft, true)+"/"+toString(vRight, false)+")", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
}
|
||||
|
||||
private String toString(DataType val) throws IOException {
|
||||
private String toString(DataType val, boolean left) throws IOException {
|
||||
if (val instanceof PrimitiveType)
|
||||
return "\"" + ((PrimitiveType) val).getValueAsString()+"\"";
|
||||
|
||||
IParser jp = session.getContext().newJsonParser();
|
||||
IParser jp = left ? session.getContextLeft().newJsonParser() : session.getContextRight().newJsonParser();
|
||||
return jp.composeString(val, "value");
|
||||
}
|
||||
|
||||
|
@ -468,13 +483,13 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
private Collection<? extends TypeRefComponent> unionTypes(ProfileComparison comp, StructuralMatch<ElementDefinition> 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);
|
||||
checkAddTypeUnion(comp, res, path, result, l, session.getContextLeft());
|
||||
for (TypeRefComponent r : right)
|
||||
checkAddTypeUnion(comp, res, path, result, r);
|
||||
checkAddTypeUnion(comp, res, path, result, r, session.getContextRight());
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<TypeRefComponent> results, TypeRefComponent nw) throws DefinitionException, IOException, FHIRFormatError {
|
||||
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, List<TypeRefComponent> results, TypeRefComponent nw, IWorkerContext ctxt) throws DefinitionException, IOException, FHIRFormatError {
|
||||
boolean pfound = false;
|
||||
boolean tfound = false;
|
||||
nw = nw.copy();
|
||||
|
@ -491,15 +506,15 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
ex.setProfile(null);
|
||||
} else {
|
||||
// both have profiles. Is one derived from the other?
|
||||
StructureDefinition sdex = session.getContext().fetchResource(StructureDefinition.class, ex.getProfile().get(0).getValue());
|
||||
StructureDefinition sdnw = session.getContext().fetchResource(StructureDefinition.class, nw.getProfile().get(0).getValue());
|
||||
StructureDefinition sdex = ((IWorkerContext) ex.getUserData("ctxt")).fetchResource(StructureDefinition.class, ex.getProfile().get(0).getValue());
|
||||
StructureDefinition sdnw = ctxt.fetchResource(StructureDefinition.class, nw.getProfile().get(0).getValue());
|
||||
if (sdex != null && sdnw != null) {
|
||||
if (sdex == sdnw) {
|
||||
if (sdex.getUrl().equals(sdnw.getUrl())) {
|
||||
pfound = true;
|
||||
} else if (derivesFrom(sdex, sdnw)) {
|
||||
} else if (derivesFrom(sdex, sdnw, ((IWorkerContext) ex.getUserData("ctxt")))) {
|
||||
ex.setProfile(nw.getProfile());
|
||||
pfound = true;
|
||||
} else if (derivesFrom(sdnw, sdex)) {
|
||||
} else if (derivesFrom(sdnw, sdex, ctxt)) {
|
||||
pfound = true;
|
||||
} else if (sdnw.getSnapshot().getElement().get(0).getPath().equals(sdex.getSnapshot().getElement().get(0).getPath())) {
|
||||
ProfileComparison compP = (ProfileComparison) session.compare(sdex, sdnw);
|
||||
|
@ -519,15 +534,15 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
ex.setTargetProfile(null);
|
||||
} else {
|
||||
// both have profiles. Is one derived from the other?
|
||||
StructureDefinition sdex = session.getContext().fetchResource(StructureDefinition.class, ex.getTargetProfile().get(0).getValue());
|
||||
StructureDefinition sdnw = session.getContext().fetchResource(StructureDefinition.class, nw.getTargetProfile().get(0).getValue());
|
||||
StructureDefinition sdex = ((IWorkerContext) ex.getUserData("ctxt")).fetchResource(StructureDefinition.class, ex.getTargetProfile().get(0).getValue());
|
||||
StructureDefinition sdnw = ctxt.fetchResource(StructureDefinition.class, nw.getTargetProfile().get(0).getValue());
|
||||
if (sdex != null && sdnw != null) {
|
||||
if (sdex == sdnw) {
|
||||
if (matches(sdex, sdnw)) {
|
||||
tfound = true;
|
||||
} else if (derivesFrom(sdex, sdnw)) {
|
||||
} else if (derivesFrom(sdex, sdnw, ((IWorkerContext) ex.getUserData("ctxt")))) {
|
||||
ex.setTargetProfile(nw.getTargetProfile());
|
||||
tfound = true;
|
||||
} else if (derivesFrom(sdnw, sdex)) {
|
||||
} else if (derivesFrom(sdnw, sdex, ctxt)) {
|
||||
tfound = true;
|
||||
} else if (sdnw.getSnapshot().getElement().get(0).getPath().equals(sdex.getSnapshot().getElement().get(0).getPath())) {
|
||||
ProfileComparison compP = (ProfileComparison) session.compare(sdex, sdnw);
|
||||
|
@ -540,17 +555,33 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!tfound || !pfound)
|
||||
if (!tfound || !pfound) {
|
||||
nw.setUserData("ctxt", ctxt);
|
||||
results.add(nw);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean derivesFrom(StructureDefinition left, StructureDefinition right) {
|
||||
private boolean matches(StructureDefinition s1, StructureDefinition s2) {
|
||||
if (!s1.getUrl().equals(s2.getUrl())) {
|
||||
return false;
|
||||
}
|
||||
if (s1.getDerivation() == TypeDerivationRule.SPECIALIZATION && s2.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||
return true; // arbitrary; we're just not interested in pursuing cross version differences
|
||||
}
|
||||
if (s1.hasVersion()) {
|
||||
return s1.getVersion().equals(s2.getVersion());
|
||||
} else {
|
||||
return !s2.hasVersion();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean derivesFrom(StructureDefinition left, StructureDefinition right, IWorkerContext ctxt) {
|
||||
StructureDefinition sd = left;
|
||||
while (sd != null) {
|
||||
if (right.getUrl().equals(sd.getBaseDefinition())) {
|
||||
return true;
|
||||
}
|
||||
sd = sd.hasBaseDefinition() ? session.getContext().fetchResource(StructureDefinition.class, sd.getBaseDefinition()) : null;
|
||||
sd = sd.hasBaseDefinition() ? ctxt.fetchResource(StructureDefinition.class, sd.getBaseDefinition()) : null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -574,14 +605,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
pfound = true;
|
||||
c.setProfile(r.getProfile());
|
||||
} else {
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getProfile().get(0).getValue(), comp.getLeft().getName());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getProfile().get(0).getValue(), comp.getRight().getName());
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getProfile().get(0).getValue(), comp.getLeft().getName(), session.getContextLeft());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getProfile().get(0).getValue(), comp.getRight().getName(), session.getContextRight());
|
||||
if (sdl != null && sdr != null) {
|
||||
if (sdl == sdr) {
|
||||
pfound = true;
|
||||
} else if (derivesFrom(sdl, sdr)) {
|
||||
} else if (derivesFrom(sdl, sdr, session.getContextLeft())) {
|
||||
pfound = true;
|
||||
} else if (derivesFrom(sdr, sdl)) {
|
||||
} else if (derivesFrom(sdr, sdl, session.getContextRight())) {
|
||||
c.setProfile(r.getProfile());
|
||||
pfound = true;
|
||||
} else if (sdl.getType().equals(sdr.getType())) {
|
||||
|
@ -601,14 +632,14 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
tfound = true;
|
||||
c.setTargetProfile(r.getTargetProfile());
|
||||
} else {
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getTargetProfile().get(0).getValue(), comp.getLeft().getName());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getTargetProfile().get(0).getValue(), comp.getRight().getName());
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getTargetProfile().get(0).getValue(), comp.getLeft().getName(), session.getContextLeft());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getTargetProfile().get(0).getValue(), comp.getRight().getName(), session.getContextRight());
|
||||
if (sdl != null && sdr != null) {
|
||||
if (sdl == sdr) {
|
||||
if (matches(sdl, sdr)) {
|
||||
tfound = true;
|
||||
} else if (derivesFrom(sdl, sdr)) {
|
||||
} else if (derivesFrom(sdl, sdr, session.getContextLeft())) {
|
||||
tfound = true;
|
||||
} else if (derivesFrom(sdr, sdl)) {
|
||||
} else if (derivesFrom(sdr, sdl, session.getContextRight())) {
|
||||
c.setTargetProfile(r.getTargetProfile());
|
||||
tfound = true;
|
||||
} else if (sdl.getType().equals(sdr.getType())) {
|
||||
|
@ -713,8 +744,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return true;
|
||||
} else {
|
||||
// ok, now we compare the value sets. This may be unresolvable.
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet());
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet(), session.getContextLeft());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet(), session.getContextRight());
|
||||
if (lvs == null) {
|
||||
vm(IssueSeverity.ERROR, "Unable to resolve left value set "+left.getValueSet().toString()+" at "+path, path, comp.getMessages(), res.getMessages());
|
||||
return true;
|
||||
|
@ -739,6 +770,9 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (!lvs.getUrl().equals(rvs.getUrl())) {
|
||||
return false;
|
||||
}
|
||||
if (isCore(lvs) && isCore(rvs)) {
|
||||
return true;
|
||||
}
|
||||
if (lvs.hasVersion()) {
|
||||
if (!lvs.getVersion().equals(rvs.getVersion())) {
|
||||
return false;
|
||||
|
@ -749,6 +783,10 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean isCore(ValueSet vs) {
|
||||
return vs.getUrl().startsWith("http://hl7.org/fhir/ValueSet");
|
||||
}
|
||||
|
||||
private List<ElementDefinitionConstraintComponent> intersectConstraints(String path, List<ElementDefinitionConstraintComponent> left, List<ElementDefinitionConstraintComponent> right) {
|
||||
List<ElementDefinitionConstraintComponent> result = new ArrayList<ElementDefinitionConstraintComponent>();
|
||||
for (ElementDefinitionConstraintComponent l : left) {
|
||||
|
@ -771,7 +809,9 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (Utilities.equals(r.getId(), l.getId()) || (Utilities.equals(r.getXpath(), l.getXpath()) && r.getSeverity() == l.getSeverity()))
|
||||
found = true;
|
||||
if (!found) {
|
||||
vm(IssueSeverity.INFORMATION, "StructureDefinition "+comp.getLeft().getName()+" has a constraint that is removed in "+comp.getRight().getName()+" and it is uncertain whether they are compatible ("+l.getExpression()+")", path, comp.getMessages(), res.getMessages());
|
||||
if (!Utilities.existsInList(l.getExpression(), "hasValue() or (children().count() > id.count())", "extension.exists() != value.exists()")) {
|
||||
vm(IssueSeverity.INFORMATION, "StructureDefinition "+comp.getLeft().getName()+" has a constraint that is removed in "+comp.getRight().getName()+" and it is uncertain whether they are compatible ("+l.getExpression()+")", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
}
|
||||
result.add(l);
|
||||
}
|
||||
|
@ -781,14 +821,16 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (Utilities.equals(r.getId(), l.getId()) || (Utilities.equals(r.getXpath(), l.getXpath()) && r.getSeverity() == l.getSeverity()))
|
||||
found = true;
|
||||
if (!found) {
|
||||
vm(IssueSeverity.INFORMATION, "StructureDefinition "+comp.getRight().getName()+" has added constraint that is not found in "+comp.getLeft().getName()+" and it is uncertain whether they are compatible ("+r.getExpression()+")", path, comp.getMessages(), res.getMessages());
|
||||
if (!Utilities.existsInList(r.getExpression(), "hasValue() or (children().count() > id.count())", "extension.exists() != value.exists()")) {
|
||||
vm(IssueSeverity.INFORMATION, "StructureDefinition "+comp.getRight().getName()+" has added constraint that is not found in "+comp.getLeft().getName()+" and it is uncertain whether they are compatible ("+r.getExpression()+")", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String url, String name) {
|
||||
StructureDefinition sd = session.getContext().fetchResource(StructureDefinition.class, url);
|
||||
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinition> 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);
|
||||
}
|
||||
|
@ -809,8 +851,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (Base.compareDeep(left.getValueSet(), right.getValueSet(), false))
|
||||
union.setValueSet(left.getValueSet());
|
||||
else {
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet());
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet(), session.getContextLeft());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet(), session.getContextRight());
|
||||
if (lvs != null && rvs != null) {
|
||||
ValueSetComparison compP = (ValueSetComparison) session.compare(lvs, rvs);
|
||||
if (compP != null) {
|
||||
|
@ -825,15 +867,15 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return union;
|
||||
}
|
||||
|
||||
private ValueSet resolveVS(StructureDefinition ctxtLeft, String vsRef) {
|
||||
private ValueSet resolveVS(StructureDefinition ctxtLeft, String vsRef, IWorkerContext ctxt) {
|
||||
if (vsRef == null)
|
||||
return null;
|
||||
return session.getContext().fetchResource(ValueSet.class, vsRef);
|
||||
return ctxt.fetchResource(ValueSet.class, vsRef);
|
||||
}
|
||||
|
||||
public XhtmlNode renderStructure(ProfileComparison comp, String id, String prefix, String corePath) throws FHIRException, IOException {
|
||||
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(Utilities.path("[tmp]", "compare"), false, true);
|
||||
gen.setTranslator(session.getContext().translator());
|
||||
gen.setTranslator(session.getContextRight().translator());
|
||||
TableModel model = gen.initComparisonTable(corePath, id);
|
||||
genElementComp(null /* oome back to this later */, gen, model.getRows(), comp.combined, corePath, prefix, null, true);
|
||||
return gen.generate(model, prefix, 0, null);
|
||||
|
@ -849,7 +891,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
rows.add(row);
|
||||
String path = combined.either().getPath();
|
||||
row.setAnchor(path);
|
||||
row.setColor(utils.getRowColor(combined.either(), false));
|
||||
row.setColor(utilsRight.getRowColor(combined.either(), false));
|
||||
if (eitherHasSlicing(combined))
|
||||
row.setLineColor(1);
|
||||
else if (eitherHasSliceName(combined))
|
||||
|
@ -895,17 +937,17 @@ 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 = utils.genElementNameCell(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
nc = utilsRight.genElementNameCell(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
} else {
|
||||
nc = utils.genElementNameCell(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
nc = utilsRight.genElementNameCell(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
}
|
||||
if (combined.hasLeft()) {
|
||||
frame(utils.genElementCells(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName, nc), leftColor);
|
||||
frame(utilsRight.genElementCells(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName, nc), leftColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), leftColor);
|
||||
}
|
||||
if (combined.hasRight()) {
|
||||
frame(utils.genElementCells(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used, ref, sName, nc), rightColor);
|
||||
frame(utilsRight.genElementCells(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used, ref, sName, nc), rightColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), rightColor);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,13 @@ package org.hl7.fhir.r5.comparison;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
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.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
|
@ -14,11 +21,37 @@ import org.hl7.fhir.utilities.xhtml.NodeType;
|
|||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class ResourceComparer {
|
||||
|
||||
public static class MessageCounts {
|
||||
private int errors;
|
||||
private int warnings;
|
||||
private int hints;
|
||||
public int getErrors() {
|
||||
return errors;
|
||||
}
|
||||
public int getWarnings() {
|
||||
return warnings;
|
||||
}
|
||||
public int getHints() {
|
||||
return hints;
|
||||
}
|
||||
public void error() {
|
||||
errors++;
|
||||
}
|
||||
public void warning() {
|
||||
warnings++;
|
||||
}
|
||||
public void hint() {
|
||||
hints++;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ResourceComparison {
|
||||
|
||||
public static abstract class ResourceComparison {
|
||||
private String id;
|
||||
private String leftId;
|
||||
private String rightId;
|
||||
private MessageCounts cnts;
|
||||
|
||||
public ResourceComparison(String leftId, String rightId) {
|
||||
super();
|
||||
|
@ -48,14 +81,144 @@ public class ResourceComparer {
|
|||
}
|
||||
|
||||
protected abstract String summary();
|
||||
|
||||
protected abstract String fhirType();
|
||||
|
||||
protected abstract String toTable();
|
||||
|
||||
protected String color() {
|
||||
if (hasErrors()) {
|
||||
return COLOR_DIFFERENT;
|
||||
} else if (noChange()) {
|
||||
return COLOR_NO_CHANGE;
|
||||
} else {
|
||||
return COLOR_DIFFERENT_LESS;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasErrors() {
|
||||
MessageCounts cnts = getCounts();
|
||||
return cnts.getErrors() > 0;
|
||||
}
|
||||
|
||||
protected boolean noChange() {
|
||||
MessageCounts cnts = getCounts();
|
||||
return cnts.getErrors() + cnts.getWarnings() + cnts.getHints() == 0;
|
||||
}
|
||||
|
||||
protected String outcomeSummary() {
|
||||
MessageCounts cnts = getCounts();
|
||||
return
|
||||
Integer.toString(cnts.getErrors())+" "+Utilities.pluralize("Breaking Change", cnts.getErrors())+", "+
|
||||
Integer.toString(cnts.getWarnings())+" "+Utilities.pluralize("Change", cnts.getWarnings())+", "+
|
||||
Integer.toString(cnts.getHints())+" "+Utilities.pluralize("Note", cnts.getHints());
|
||||
}
|
||||
|
||||
public MessageCounts getCounts() {
|
||||
if (cnts == null) {
|
||||
cnts = new MessageCounts();
|
||||
countMessages(cnts);
|
||||
}
|
||||
return cnts;
|
||||
}
|
||||
|
||||
protected abstract void countMessages(MessageCounts cnts);
|
||||
}
|
||||
|
||||
|
||||
public static class PlaceHolderComparison extends ResourceComparison {
|
||||
private CanonicalResource left;
|
||||
private CanonicalResource right;
|
||||
private Throwable e;
|
||||
|
||||
public PlaceHolderComparison(CanonicalResource left, CanonicalResource right) {
|
||||
super(left == null ? right.getId() : left.getId(), right == null ? left.getId() : right.getId());
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public PlaceHolderComparison(CanonicalResource left, CanonicalResource right, Throwable e) {
|
||||
super(left == null ? right.getId() : left.getId(), right == null ? left.getId() : right.getId());
|
||||
this.e = e;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String abbreviation() {
|
||||
CanonicalResource cr = left == null ? right : left;
|
||||
if (cr instanceof CodeSystem) {
|
||||
return "cs";
|
||||
} else if (cr instanceof ValueSet) {
|
||||
return "vs";
|
||||
} else if (cr instanceof StructureDefinition) {
|
||||
return "sd";
|
||||
} else {
|
||||
return "xx";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String summary() {
|
||||
if (e != null) {
|
||||
return e.getMessage();
|
||||
}
|
||||
CanonicalResource cr = left == null ? right : left;
|
||||
return cr.fhirType()+(left == null ? " Added" : " Removed");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String fhirType() {
|
||||
CanonicalResource cr = left == null ? right : left;
|
||||
return cr.fhirType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toTable() {
|
||||
String s = null;
|
||||
String color = null;
|
||||
if (left != null && right != null && !left.getUrl().equals(right.getUrl())) {
|
||||
s = "<td>"+left.getUrl()+"</td><td>"+right.getUrl()+"</td>";
|
||||
} else if (left != null) {
|
||||
s = "<td colspan=2>"+left.getUrl()+"</td>";
|
||||
} else {
|
||||
s = "<td colspan=2>"+right.getUrl()+"</td>";
|
||||
}
|
||||
if (left == null) {
|
||||
s = s + "<td>Added</td>";
|
||||
color = COLOR_NO_ROW_LEFT;
|
||||
} else if (right == null) {
|
||||
s = s + "<td>Removed</td>";
|
||||
color = COLOR_NO_ROW_RIGHT;
|
||||
} else {
|
||||
s = s + "<td><a href=\""+getId()+".html\">Failed<a></td>";
|
||||
color = COLOR_ISSUE;
|
||||
}
|
||||
s = s + "<td>"+(e != null ? Utilities.escapeXml(e.getMessage()) : "")+"</td>";
|
||||
return "<tr style=\"background-color: "+color+"\">"+s+"</tr>\r\n";
|
||||
}
|
||||
|
||||
public Throwable getE() {
|
||||
return e;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void countMessages(MessageCounts cnts) {
|
||||
if (e != null) {
|
||||
cnts.error();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final static String COLOR_NO_ROW_LEFT = "#ffffb3";
|
||||
public final static String COLOR_NO_CELL_LEFT = "#ffff4d";
|
||||
public final static String COLOR_NO_ROW_RIGHT = "#ffecb3";
|
||||
public final static String COLOR_NO_CELL_RIGHT = "#ffcc33";
|
||||
public final static String COLOR_DIFFERENT = "#f0b3ff";
|
||||
public final static String COLOR_DIFFERENT_LESS = "#f8e6ff";
|
||||
public final static String COLOR_ISSUE = "#ffad99";
|
||||
public final static String COLOR_NO_CHANGE = "#ffffff";
|
||||
|
||||
protected ComparisonSession session;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.hl7.fhir.r5.comparison;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
|
||||
|
@ -87,5 +88,21 @@ public class StructuralMatch<T> {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void countMessages(MessageCounts cnts) {
|
||||
for (ValidationMessage vm : getMessages()) {
|
||||
if (vm.getLevel() == IssueSeverity.ERROR) {
|
||||
cnts.error();
|
||||
} else if (vm.getLevel() == IssueSeverity.WARNING) {
|
||||
cnts.warning();
|
||||
} else if (vm.getLevel() == IssueSeverity.INFORMATION) {
|
||||
cnts.hint();
|
||||
}
|
||||
}
|
||||
for (StructuralMatch<T> c : children) {
|
||||
c.countMessages(cnts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -7,6 +7,8 @@ import java.util.List;
|
|||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.Element;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
|
@ -66,7 +68,26 @@ public class ValueSetComparer extends CanonicalResourceComparer {
|
|||
@Override
|
||||
protected String summary() {
|
||||
return "ValueSet: "+left.present()+" vs "+right.present();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String fhirType() {
|
||||
return "ValueSet";
|
||||
}
|
||||
@Override
|
||||
protected void countMessages(MessageCounts cnts) {
|
||||
super.countMessages(cnts);
|
||||
if (includes != null) {
|
||||
includes.countMessages(cnts);
|
||||
}
|
||||
if (excludes != null) {
|
||||
excludes.countMessages(cnts);
|
||||
}
|
||||
if (expansion != null) {
|
||||
expansion.countMessages(cnts);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ValueSetComparer(ComparisonSession session) {
|
||||
|
@ -372,16 +393,16 @@ public class ValueSetComparer extends CanonicalResourceComparer {
|
|||
}
|
||||
|
||||
private void compareExpansions(ValueSet left, ValueSet right, ValueSetComparison res) {
|
||||
ValueSet expL = left.hasExpansion() ? left : expand(left, res, "left");
|
||||
ValueSet expR = left.hasExpansion() ? left : expand(right, res, "right");
|
||||
ValueSet expL = left.hasExpansion() ? left : expand(left, res, "left", session.getContextLeft());
|
||||
ValueSet expR = left.hasExpansion() ? left : expand(right, res, "right", session.getContextRight());
|
||||
if (expL != null && expR != null) {
|
||||
// ignore the parameters for now
|
||||
compareConcepts(expL.getExpansion().getContains(), expR.getExpansion().getContains(), res.forceExpansion(), res.getUnion().getExpansion().getContains(), res.getIntersection().getExpansion().getContains(), "ValueSet.expansion.contains", res);
|
||||
}
|
||||
}
|
||||
|
||||
private ValueSet expand(ValueSet vs, ValueSetComparison res, String name) {
|
||||
ValueSetExpansionOutcome vse =session.getContext().expandVS(vs, true, false);
|
||||
private ValueSet expand(ValueSet vs, ValueSetComparison res, String name, IWorkerContext ctxt) {
|
||||
ValueSetExpansionOutcome vse = ctxt.expandVS(vs, true, false);
|
||||
if (vse.getValueset() != null) {
|
||||
return vse.getValueset();
|
||||
} else {
|
||||
|
@ -682,6 +703,11 @@ public class ValueSetComparer extends CanonicalResourceComparer {
|
|||
p.tx("Unable to generate expansion - see errors");
|
||||
return p;
|
||||
}
|
||||
if (csc.getExpansion().getChildren().isEmpty()) {
|
||||
XhtmlNode p = new XhtmlNode(NodeType.Element, "p");
|
||||
p.tx("Expansion is empty");
|
||||
return p;
|
||||
}
|
||||
// columns: code(+system), version, display , abstract, inactive,
|
||||
boolean hasSystem = csc.getExpansion().getChildren().isEmpty() ? false : getSystemVaries(csc.getExpansion(), csc.getExpansion().getChildren().get(0).either().getSystem());
|
||||
boolean hasVersion = findVersion(csc.getExpansion());
|
||||
|
|
|
@ -645,7 +645,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
wt = "OperationOutcome";
|
||||
}
|
||||
if (!sd.getType().equals(wt)) {
|
||||
boolean ok = isCompatibleType(wt, sd.getType());
|
||||
boolean ok = isCompatibleType(wt, sd);
|
||||
if (!ok) {
|
||||
String smsg = "The profile "+u.getValue()+" has type "+sd.getType()+" which is not consistent with the stated type "+wt;
|
||||
if (exception)
|
||||
|
@ -714,10 +714,17 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
|
||||
private boolean isCompatibleType(String base, String type) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(type);
|
||||
private boolean isCompatibleType(String base, StructureDefinition sdt) {
|
||||
StructureDefinition sdb = context.fetchTypeDefinition(base);
|
||||
if (sdb.getType().equals(sdt.getType())) {
|
||||
return true;
|
||||
}
|
||||
StructureDefinition sd = context.fetchTypeDefinition(sdt.getType());
|
||||
while (sd != null) {
|
||||
if (sd.getType().equals(base)) {
|
||||
if (sd.getType().equals(sdb.getType())) {
|
||||
return true;
|
||||
}
|
||||
if (sd.getUrl().equals(sdb.getUrl())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
|
@ -1201,7 +1208,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
if (hasInnerDiffMatches(differential, currentBase.getPath(), diffCursor, diffLimit, base.getElement(), false)) {
|
||||
if (baseHasChildren(base, currentBase)) { // not a new type here
|
||||
throw new Error("This situation is not yet (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ "+cpath+" | "+currentBase.getPath()+")");
|
||||
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ "+cpath+" | "+currentBase.getPath()+")");
|
||||
} else {
|
||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome);
|
||||
contextName = dt.getUrl();
|
||||
|
@ -4608,6 +4615,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
this.snapshot = snapshot;
|
||||
this.prefixLength = prefixLength;
|
||||
this.base = base;
|
||||
if (Utilities.isAbsoluteUrl(base)) {
|
||||
throw new Error("Wrong!");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
@ -4654,9 +4664,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
if (mandatory) {
|
||||
if (prefixLength == 0)
|
||||
errors.add("Differential contains path "+path+" which is not found in the base");
|
||||
errors.add("Differential contains path "+path+" which is not found in the in base "+name);
|
||||
else
|
||||
errors.add("Differential contains path "+path+" which is actually "+actual+", which is not found in the base");
|
||||
errors.add("Differential contains path "+path+" which is actually "+actual+", which is not found in the in base "+name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -4812,12 +4822,12 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (profile==null)
|
||||
ccmp = null; // this might happen before everything is loaded. And we don't so much care about sot order in this case
|
||||
else
|
||||
ccmp = new ElementDefinitionComparer(true, profile.getSnapshot().getElement(), ed.getType().get(0).getWorkingCode(), child.getSelf().getPath().length(), cmp.name);
|
||||
ccmp = new ElementDefinitionComparer(true, profile.getSnapshot().getElement(), resolveType(ed.getType().get(0).getWorkingCode()), child.getSelf().getPath().length(), cmp.name);
|
||||
} else if (ed.getType().size() == 1 && !ed.getType().get(0).getWorkingCode().equals("*")) {
|
||||
StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(ed.getType().get(0).getWorkingCode()));
|
||||
if (profile==null)
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_PROFILE__IN_ELEMENT_, sdNs(ed.getType().get(0).getWorkingCode()), ed.getPath()));
|
||||
ccmp = new ElementDefinitionComparer(false, profile.getSnapshot().getElement(), ed.getType().get(0).getWorkingCode(), child.getSelf().getPath().length(), cmp.name);
|
||||
ccmp = new ElementDefinitionComparer(false, profile.getSnapshot().getElement(), resolveType(ed.getType().get(0).getWorkingCode()), child.getSelf().getPath().length(), cmp.name);
|
||||
} else if (child.getSelf().getType().size() == 1) {
|
||||
StructureDefinition profile = context.fetchResource(StructureDefinition.class, sdNs(child.getSelf().getType().get(0).getWorkingCode()));
|
||||
if (profile==null)
|
||||
|
@ -4860,6 +4870,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return ccmp;
|
||||
}
|
||||
|
||||
private String resolveType(String code) {
|
||||
if (Utilities.isAbsoluteUrl(code)) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, code);
|
||||
if (sd != null) {
|
||||
return sd.getType();
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
private static String sdNs(String type) {
|
||||
return sdNs(type, null);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.hl7.fhir.r5.context;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -614,21 +616,28 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
p.setParameter("includeDefinition", false);
|
||||
p.setParameter("excludeNested", !heirarchical);
|
||||
|
||||
List<String> allErrors = new ArrayList<>();
|
||||
|
||||
// ok, first we try to expand locally
|
||||
ValueSetExpanderSimple vse = new ValueSetExpanderSimple(this);
|
||||
try {
|
||||
ValueSetExpanderSimple vse = new ValueSetExpanderSimple(this);
|
||||
res = vse.doExpand(vs, p);
|
||||
if (!res.getValueset().hasUrl()) {
|
||||
throw new Error(formatMessage(I18nConstants.NO_URL_IN_EXPAND_VALUE_SET));
|
||||
res = vse.expand(vs, p);
|
||||
allErrors.addAll(vse.getAllErrors());
|
||||
if (res.getValueset() != null) {
|
||||
if (!res.getValueset().hasUrl()) {
|
||||
throw new Error(formatMessage(I18nConstants.NO_URL_IN_EXPAND_VALUE_SET));
|
||||
}
|
||||
txCache.cacheExpansion(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||
return res;
|
||||
}
|
||||
txCache.cacheExpansion(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
allErrors.addAll(vse.getAllErrors());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// if that failed, we try to expand on the server
|
||||
if (noTerminologyServer) {
|
||||
return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE);
|
||||
return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE, allErrors);
|
||||
}
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("_limit", Integer.toString(expandCodesLimit ));
|
||||
|
@ -644,13 +653,12 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
res = new ValueSetExpansionOutcome(result).setTxLink(txLog.getLastId());
|
||||
} catch (Exception e) {
|
||||
res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||
res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, allErrors).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||
}
|
||||
txCache.cacheExpansion(cacheToken, res, TerminologyCache.PERMANENT);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private boolean hasTooCostlyExpansion(ValueSet valueset) {
|
||||
return valueset != null && valueset.hasExpansion() && ToolingExtensions.hasExtension(valueset.getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY);
|
||||
}
|
||||
|
@ -842,6 +850,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
// --------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public void initTS(String cachePath) throws Exception {
|
||||
if (!new File(cachePath).exists()) {
|
||||
Utilities.createDirectory(cachePath);
|
||||
}
|
||||
txCache = new TerminologyCache(lock, cachePath);
|
||||
}
|
||||
|
||||
|
@ -1603,4 +1614,12 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getTxCache() {
|
||||
return txCache.getFolder();
|
||||
}
|
||||
|
||||
public TerminologyClient getTxClient() {
|
||||
return txClient;
|
||||
}
|
||||
|
||||
}
|
|
@ -64,10 +64,13 @@ import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorCla
|
|||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||
import org.hl7.fhir.utilities.TranslationServices;
|
||||
import org.hl7.fhir.utilities.cache.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
|
||||
/**
|
||||
* This is the standard interface used for access to underlying FHIR
|
||||
|
@ -150,7 +153,18 @@ public interface IWorkerContext {
|
|||
* @param resource
|
||||
* @return null if not tracking paths
|
||||
*/
|
||||
String getResourcePath(Resource resource);
|
||||
String getResourcePath(Resource resource);
|
||||
|
||||
/**
|
||||
* called when a mew package is being loaded
|
||||
*
|
||||
* this is called by loadPacakgeAndDependencies when a new package is loaded
|
||||
* @param npm
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws JsonSyntaxException
|
||||
*/
|
||||
IContextResourceLoader getNewLoader(NpmPackage npm) throws JsonSyntaxException, IOException;
|
||||
}
|
||||
|
||||
|
||||
|
@ -660,7 +674,45 @@ public interface IWorkerContext {
|
|||
public String getLinkForUrl(String corePath, String s);
|
||||
public Map<String, byte[]> getBinaries();
|
||||
|
||||
void loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String[] types) throws FileNotFoundException, IOException, FHIRException;
|
||||
/**
|
||||
* Load relevant resources of the appropriate types (as specified by the loader) from the nominated package
|
||||
*
|
||||
* note that the package system uses lazy loading; the loader will be called later when the classes that use the context need the relevant resource
|
||||
*
|
||||
* @param pi - the package to load
|
||||
* @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version).
|
||||
* @return the number of resources loaded
|
||||
*/
|
||||
int loadFromPackage(NpmPackage pi, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException;
|
||||
|
||||
/**
|
||||
* Load relevant resources of the appropriate types (as specified by the loader) from the nominated package
|
||||
*
|
||||
* note that the package system uses lazy loading; the loader will be called later when the classes that use the context need the relevant resource
|
||||
*
|
||||
* Deprecated - use the simpler method where the types come from the loader.
|
||||
*
|
||||
* @param pi - the package to load
|
||||
* @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version).
|
||||
* @param types - which types of resources to load
|
||||
* @return the number of resources loaded
|
||||
*/
|
||||
@Deprecated
|
||||
int loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String[] types) throws FileNotFoundException, IOException, FHIRException;
|
||||
|
||||
/**
|
||||
* Load relevant resources of the appropriate types (as specified by the loader) from the nominated package
|
||||
*
|
||||
* note that the package system uses lazy loading; the loader will be called later when the classes that use the context need the relevant resource
|
||||
*
|
||||
* This method also loads all the packages that the package depends on (recursively)
|
||||
*
|
||||
* @param pi - the package to load
|
||||
* @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version).
|
||||
* @param pcm - used to find and load additional dependencies
|
||||
* @return the number of resources loaded
|
||||
*/
|
||||
int loadFromPackageAndDependencies(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm) throws FileNotFoundException, IOException, FHIRException;
|
||||
|
||||
public boolean hasPackage(String id, String ver);
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ import org.hl7.fhir.utilities.validation.ValidationMessage;
|
|||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
||||
/*
|
||||
|
@ -370,7 +372,46 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
|
||||
|
||||
@Override
|
||||
public void loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String... types) throws FileNotFoundException, IOException, FHIRException {
|
||||
public int loadFromPackage(NpmPackage pi, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException {
|
||||
return loadFromPackageInt(pi, loader, loader == null ? defaultTypesToLoad() : loader.getTypes());
|
||||
}
|
||||
|
||||
public static String[] defaultTypesToLoad() {
|
||||
// there's no penalty for listing resources that don't exist, so we just all the relevant possibilities for all versions
|
||||
return new String[] {"CodeSystem", "ValueSet", "ConceptMap", "NamingSystem",
|
||||
"StructureDefinition", "StructureMap",
|
||||
"SearchParameter", "OperationDefinition", "CapabilityStatement", "Conformance",
|
||||
"Questionnaire", "ImplementationGuide" };
|
||||
}
|
||||
|
||||
@Override
|
||||
public int loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String[] types) throws FileNotFoundException, IOException, FHIRException {
|
||||
return loadFromPackageInt(pi, loader, types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int loadFromPackageAndDependencies(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm) throws FileNotFoundException, IOException, FHIRException {
|
||||
return loadFromPackageAndDependenciesInt(pi, loader, pcm, pi.name()+"#"+pi.version());
|
||||
}
|
||||
public int loadFromPackageAndDependenciesInt(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm, String path) throws FileNotFoundException, IOException, FHIRException {
|
||||
int t = 0;
|
||||
|
||||
for (String e : pi.dependencies()) {
|
||||
if (!loadedPackages.contains(e) && !VersionUtilities.isCorePackage(e)) {
|
||||
NpmPackage npm = pcm.loadPackage(e);
|
||||
if (!version.equals(npm.fhirVersion())) {
|
||||
System.out.println(formatMessage(I18nConstants.PACKAGE_VERSION_MISMATCH, e, version, npm.fhirVersion(), path));
|
||||
}
|
||||
t = t + loadFromPackageAndDependenciesInt(npm, loader.getNewLoader(npm), pcm, path+" -> "+npm.name()+"#"+npm.version());
|
||||
}
|
||||
}
|
||||
t = t + loadFromPackageInt(pi, loader, loader.getTypes());
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
public int loadFromPackageInt(NpmPackage pi, IContextResourceLoader loader, String... types) throws FileNotFoundException, IOException, FHIRException {
|
||||
int t = 0;
|
||||
if (progress) {
|
||||
System.out.println("Load Package "+pi.name()+"#"+pi.version());
|
||||
}
|
||||
|
@ -388,6 +429,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
for (String s : pi.listResources(loader.getTypes())) {
|
||||
try {
|
||||
loadDefinitionItem(s, pi.load("package", s), loader, null, new PackageVersion(pi.id(), pi.version()));
|
||||
t++;
|
||||
} catch (FHIRException e) {
|
||||
throw new FHIRException(formatMessage(I18nConstants.ERROR_READING__FROM_PACKAGE__, s, pi.name(), pi.version(), e.getMessage()), e);
|
||||
}
|
||||
|
@ -399,6 +441,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
for (PackageResourceInformation pri : pi.listIndexedResources(types)) {
|
||||
try {
|
||||
registerResourceFromPackage(new PackageResourceLoader(pri, loader), new PackageVersion(pi.id(), pi.version()));
|
||||
t++;
|
||||
} catch (FHIRException e) {
|
||||
throw new FHIRException(formatMessage(I18nConstants.ERROR_READING__FROM_PACKAGE__, pri.getFilename(), pi.name(), pi.version(), e.getMessage()), e);
|
||||
}
|
||||
|
@ -410,6 +453,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
if (version == null) {
|
||||
version = pi.version();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public void loadFromFile(String file, IContextResourceLoader loader) throws IOException, FHIRException {
|
||||
|
@ -757,5 +801,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -469,6 +469,10 @@ public class TerminologyCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getFolder() {
|
||||
return folder;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -611,7 +611,6 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
// x.an(v.get("id").primitiveValue());
|
||||
// }
|
||||
// }
|
||||
System.out.print("c");
|
||||
} else if (!exemptFromRendering(child)) {
|
||||
List<ElementDefinition> grandChildren = getChildrenForPath(allElements, path+"."+p.getName());
|
||||
filterGrandChildren(grandChildren, path+"."+p.getName(), p);
|
||||
|
@ -807,9 +806,14 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
String[] list = displayHint.split(";");
|
||||
for (String item : list) {
|
||||
String[] parts = item.split(":");
|
||||
if (parts.length != 2)
|
||||
throw new DefinitionException("error reading display hint: '"+displayHint+"'");
|
||||
hints.put(parts[0].trim(), parts[1].trim());
|
||||
if (parts.length == 1) {
|
||||
hints.put("value", parts[0].trim());
|
||||
} else {
|
||||
if (parts.length != 2) {
|
||||
throw new DefinitionException("error reading display hint: '"+displayHint+"'");
|
||||
}
|
||||
hints.put(parts[0].trim(), parts[1].trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ package org.hl7.fhir.r5.terminologies;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
|
@ -65,6 +67,7 @@ public interface ValueSetExpander {
|
|||
private String error;
|
||||
private TerminologyServiceErrorClass errorClass;
|
||||
private String txLink;
|
||||
private List<String> allErrors = new ArrayList<>();
|
||||
|
||||
public ValueSetExpansionOutcome(ValueSet valueset) {
|
||||
super();
|
||||
|
@ -76,18 +79,31 @@ public interface ValueSetExpander {
|
|||
this.valueset = valueset;
|
||||
this.error = error;
|
||||
this.errorClass = errorClass;
|
||||
allErrors.add(error);
|
||||
}
|
||||
public ValueSetExpansionOutcome(ValueSetChecker service, String error, TerminologyServiceErrorClass errorClass) {
|
||||
super();
|
||||
this.valueset = null;
|
||||
this.error = error;
|
||||
this.errorClass = errorClass;
|
||||
allErrors.add(error);
|
||||
}
|
||||
public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass) {
|
||||
this.valueset = null;
|
||||
this.error = error;
|
||||
this.errorClass = errorClass;
|
||||
allErrors.add(error);
|
||||
}
|
||||
public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass, List<String> errList) {
|
||||
this.valueset = null;
|
||||
this.error = error;
|
||||
this.errorClass = errorClass;
|
||||
this.allErrors.addAll(errList);
|
||||
if (!allErrors.contains(error)) {
|
||||
allErrors.add(error);
|
||||
}
|
||||
}
|
||||
|
||||
public ValueSet getValueset() {
|
||||
return valueset;
|
||||
}
|
||||
|
@ -104,7 +120,9 @@ public interface ValueSetExpander {
|
|||
this.txLink = txLink;
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<String> getAllErrors() {
|
||||
return allErrors;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -66,6 +66,7 @@ import java.io.IOException;
|
|||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -104,9 +105,6 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple.AllConceptsFilter;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple.IConceptFilter;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple.PropertyFilter;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
|
@ -128,18 +126,18 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
if (pc != null) {
|
||||
String v = pc.getValue().isPrimitive() ? pc.getValue().primitiveValue() : null;
|
||||
switch (filter.getOp()) {
|
||||
case DESCENDENTOF: throw new FHIRException("not supported yet");
|
||||
case DESCENDENTOF: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case EQUAL: return filter.getValue().equals(v);
|
||||
case EXISTS: throw new FHIRException("not supported yet");
|
||||
case GENERALIZES: throw new FHIRException("not supported yet");
|
||||
case IN: throw new FHIRException("not supported yet");
|
||||
case ISA: throw new FHIRException("not supported yet");
|
||||
case ISNOTA: throw new FHIRException("not supported yet");
|
||||
case NOTIN: throw new FHIRException("not supported yet");
|
||||
case NULL: throw new FHIRException("not supported yet");
|
||||
case REGEX: throw new FHIRException("not supported yet");
|
||||
case EXISTS: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case GENERALIZES: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case IN: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case ISA: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case ISNOTA: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case NOTIN: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case NULL: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
case REGEX: throw fail("not supported yet: "+filter.getOp().toCode());
|
||||
default:
|
||||
throw new FHIRException("Shouldn't get here");
|
||||
throw fail("Shouldn't get here");
|
||||
}
|
||||
} else if (property.getType() == PropertyType.BOOLEAN && filter.getOp() == FilterOperator.EQUAL) {
|
||||
return "false".equals(filter.getValue());
|
||||
|
@ -183,14 +181,22 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
private Set<String> excludeSystems = new HashSet<String>();
|
||||
private ValueSet focus;
|
||||
private int maxExpansionSize = 500;
|
||||
private List<String> allErrors = new ArrayList<>();
|
||||
|
||||
private int total;
|
||||
private boolean checkCodesWhenExpanding;
|
||||
|
||||
public ValueSetExpanderSimple(IWorkerContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public ValueSetExpanderSimple(IWorkerContext context, List<String> allErrors) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.allErrors = allErrors;
|
||||
}
|
||||
|
||||
public void setMaxExpansionSize(int theMaxExpansionSize) {
|
||||
maxExpansionSize = theMaxExpansionSize;
|
||||
}
|
||||
|
@ -318,7 +324,7 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
private void addCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params, Parameters expParams, List<ValueSet> filters) throws ETooCostly, FHIRException {
|
||||
if (expand != null) {
|
||||
if (expand.getContains().size() > maxExpansionSize)
|
||||
throw new ETooCostly("Too many codes to display (>" + Integer.toString(expand.getContains().size()) + ")");
|
||||
throw failCostly("Too many codes to display (>" + Integer.toString(expand.getContains().size()) + ")");
|
||||
for (ValueSetExpansionParameterComponent p : expand.getParameter()) {
|
||||
if (!existsInParams(params, p.getName(), p.getValue()))
|
||||
params.add(p);
|
||||
|
@ -343,7 +349,7 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
}
|
||||
|
||||
if (exc.hasValueSet())
|
||||
throw new Error("Processing Value set references in exclude is not yet done in "+ctxt);
|
||||
throw fail("Processing Value set references in exclude is not yet done in "+ctxt);
|
||||
// importValueSet(imp.getValue(), params, expParams);
|
||||
|
||||
CodeSystem cs = context.fetchCodeSystem(exc.getSystem());
|
||||
|
@ -351,7 +357,7 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
ValueSetExpansionOutcome vse = context.expandVS(exc, false);
|
||||
ValueSet valueset = vse.getValueset();
|
||||
if (valueset == null)
|
||||
throw new TerminologyServiceException("Error Expanding ValueSet: "+vse.getError());
|
||||
throw failTSE("Error Expanding ValueSet: "+vse.getError());
|
||||
excludeCodes(valueset.getExpansion(), params);
|
||||
return;
|
||||
}
|
||||
|
@ -361,9 +367,11 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
}
|
||||
|
||||
if (exc.getFilter().size() > 0)
|
||||
throw new NotImplementedException("not done yet");
|
||||
throw fail("not done yet - multiple filters");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void excludeCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params) {
|
||||
for (ValueSetExpansionContainsComponent c : expand.getContains()) {
|
||||
excludeCode(c.getSystem(), c.getCode());
|
||||
|
@ -380,22 +388,23 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
|
||||
@Override
|
||||
public ValueSetExpansionOutcome expand(ValueSet source, Parameters expParams) {
|
||||
allErrors.clear();
|
||||
try {
|
||||
return doExpand(source, expParams);
|
||||
return expandInternal(source, expParams);
|
||||
} catch (NoTerminologyServiceException e) {
|
||||
// well, we couldn't expand, so we'll return an interface to a checker that can check membership of the set
|
||||
// that might fail too, but it might not, later.
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.NOSERVICE);
|
||||
} catch (RuntimeException e) {
|
||||
// TODO: we should put something more specific instead of just Exception below, since
|
||||
// it swallows bugs.. what would be expected to be caught there?
|
||||
throw e;
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.NOSERVICE, allErrors);
|
||||
} catch (Exception e) {
|
||||
// well, we couldn't expand, so we'll return an interface to a checker that can check membership of the set
|
||||
// that might fail too, but it might not, later.
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.UNKNOWN);
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, allErrors);
|
||||
}
|
||||
}
|
||||
|
||||
public ValueSetExpansionOutcome expandInternal(ValueSet source, Parameters expParams) throws FHIRException, FileNotFoundException, ETooCostly, IOException {
|
||||
return doExpand(source, expParams);
|
||||
}
|
||||
|
||||
public ValueSetExpansionOutcome doExpand(ValueSet source, Parameters expParams) throws FHIRException, ETooCostly, FileNotFoundException, IOException {
|
||||
if (expParams == null)
|
||||
|
@ -467,18 +476,24 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
canBeHeirarchy = false;
|
||||
includeCodes(inc, exp, expParams, canBeHeirarchy, extensions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ValueSet importValueSet(String value, ValueSetExpansionComponent exp, Parameters expParams) throws ETooCostly, TerminologyServiceException, FileNotFoundException, IOException, FHIRFormatError {
|
||||
if (value == null)
|
||||
throw new TerminologyServiceException("unable to find value set with no identity");
|
||||
throw fail("unable to find value set with no identity");
|
||||
ValueSet vs = context.fetchResource(ValueSet.class, value);
|
||||
if (vs == null)
|
||||
throw new TerminologyServiceException("Unable to find imported value set " + value);
|
||||
ValueSetExpansionOutcome vso = new ValueSetExpanderSimple(context).expand(vs, expParams);
|
||||
if (vso.getError() != null)
|
||||
throw new TerminologyServiceException("Unable to expand imported value set: " + vso.getError());
|
||||
if (vs == null) {
|
||||
if (context.fetchResource(CodeSystem.class, value) != null) {
|
||||
throw fail("Cannot include value set "+value+" because it's actually a code system");
|
||||
} else {
|
||||
throw fail("Unable to find imported value set " + value);
|
||||
}
|
||||
}
|
||||
ValueSetExpansionOutcome vso = new ValueSetExpanderSimple(context, allErrors).expand(vs, expParams);
|
||||
if (vso.getError() != null) {
|
||||
addErrors(vso.getAllErrors());
|
||||
throw fail("Unable to expand imported value set "+vs.getUrl()+": " + vso.getError());
|
||||
}
|
||||
if (vs.hasVersion())
|
||||
if (!existsInParams(exp.getParameter(), "version", new UriType(vs.getUrl() + "|" + vs.getVersion())))
|
||||
exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("version").setValue(new UriType(vs.getUrl() + "|" + vs.getVersion())));
|
||||
|
@ -499,6 +514,14 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
return vso.getValueset();
|
||||
}
|
||||
|
||||
private void addErrors(List<String> errs) {
|
||||
for (String s : errs) {
|
||||
if (!allErrors.contains(s)) {
|
||||
allErrors.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter) throws FHIRException {
|
||||
for (ValueSetExpansionContainsComponent c : list) {
|
||||
c.checkNoModifiers("Imported Expansion in Code System", "expanding");
|
||||
|
@ -534,7 +557,7 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
private void doServerIncludeCodes(ConceptSetComponent inc, boolean heirarchical, ValueSetExpansionComponent exp, List<ValueSet> imports, Parameters expParams, List<Extension> extensions) throws FHIRException {
|
||||
ValueSetExpansionOutcome vso = context.expandVS(inc, heirarchical);
|
||||
if (vso.getError() != null) {
|
||||
throw new TerminologyServiceException("Unable to expand imported value set: " + vso.getError());
|
||||
throw failTSE("Unable to expand imported value set: " + vso.getError());
|
||||
}
|
||||
ValueSet vs = vso.getValueset();
|
||||
if (vs.hasVersion()) {
|
||||
|
@ -571,13 +594,13 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException {
|
||||
if (cs == null) {
|
||||
if (context.isNoTerminologyServer())
|
||||
throw new NoTerminologyServiceException("Unable to find code system " + inc.getSystem().toString());
|
||||
throw failTSE("Unable to find code system " + inc.getSystem().toString());
|
||||
else
|
||||
throw new TerminologyServiceException("Unable to find code system " + inc.getSystem().toString());
|
||||
throw failTSE("Unable to find code system " + inc.getSystem().toString());
|
||||
}
|
||||
cs.checkNoModifiers("Code System", "expanding");
|
||||
if (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT)
|
||||
throw new TerminologyServiceException("Code system " + inc.getSystem().toString() + " is incomplete");
|
||||
throw failTSE("Code system " + inc.getSystem().toString() + " is incomplete");
|
||||
if (cs.hasVersion())
|
||||
if (!existsInParams(exp.getParameter(), "version", new UriType(cs.getUrl() + "|" + cs.getVersion())))
|
||||
exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("version").setValue(new UriType(cs.getUrl() + "|" + cs.getVersion())));
|
||||
|
@ -602,7 +625,9 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
|
||||
addFragmentWarning(exp, cs);
|
||||
} else {
|
||||
throw new TerminologyServiceException("Unable to find code '" + c.getCode() + "' in code system " + cs.getUrl());
|
||||
if (checkCodesWhenExpanding) {
|
||||
throw failTSE("Unable to find code '" + c.getCode() + "' in code system " + cs.getUrl());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
inactive = CodeSystemUtilities.isInactive(cs, def);
|
||||
|
@ -612,7 +637,7 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
}
|
||||
if (inc.getFilter().size() > 1) {
|
||||
canBeHeirarchy = false; // which will bt the case if we get around to supporting this
|
||||
throw new TerminologyServiceException("Multiple filters not handled yet"); // need to and them, and this isn't done yet. But this shouldn't arise in non loinc and snomed value sets
|
||||
throw failTSE("Multiple filters not handled yet"); // need to and them, and this isn't done yet. But this shouldn't arise in non loinc and snomed value sets
|
||||
}
|
||||
if (inc.getFilter().size() == 1) {
|
||||
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
|
||||
|
@ -623,13 +648,13 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
// special: all codes in the target code system under the value
|
||||
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
|
||||
if (def == null)
|
||||
throw new TerminologyServiceException("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter());
|
||||
} else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) {
|
||||
// special: all codes in the target code system that are not under the value
|
||||
ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue());
|
||||
if (defEx == null)
|
||||
throw new TerminologyServiceException("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter());
|
||||
}
|
||||
|
@ -637,7 +662,7 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
// special: all codes in the target code system under the value
|
||||
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
|
||||
if (def == null)
|
||||
throw new TerminologyServiceException("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
|
||||
for (ConceptDefinitionComponent c : def.getConcept())
|
||||
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter());
|
||||
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
|
||||
|
@ -663,7 +688,7 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())));
|
||||
}
|
||||
} else {
|
||||
throw new NotImplementedException("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
|
||||
throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -714,4 +739,31 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
|||
return key(c.getSystem(), c.getCode());
|
||||
}
|
||||
|
||||
private FHIRException fail(String msg) {
|
||||
allErrors.add(msg);
|
||||
return new FHIRException(msg);
|
||||
}
|
||||
|
||||
private ETooCostly failCostly(String msg) {
|
||||
allErrors.add(msg);
|
||||
return new ETooCostly(msg);
|
||||
}
|
||||
|
||||
private TerminologyServiceException failTSE(String msg) {
|
||||
allErrors.add(msg);
|
||||
return new TerminologyServiceException(msg);
|
||||
}
|
||||
|
||||
public Collection<? extends String> getAllErrors() {
|
||||
return allErrors;
|
||||
}
|
||||
|
||||
public boolean isCheckCodesWhenExpanding() {
|
||||
return checkCodesWhenExpanding;
|
||||
}
|
||||
|
||||
public void setCheckCodesWhenExpanding(boolean checkCodesWhenExpanding) {
|
||||
this.checkCodesWhenExpanding = checkCodesWhenExpanding;
|
||||
}
|
||||
|
||||
}
|
|
@ -87,6 +87,11 @@ public class SnapShotGenerationTests {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IContextResourceLoader getNewLoader(NpmPackage npm) {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum TestFetchMode {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.hl7.fhir.utilities.cache;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -155,4 +156,8 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
|
|||
}
|
||||
}
|
||||
|
||||
public NpmPackage loadPackage(String idAndVer) throws FHIRException, IOException {
|
||||
return loadPackage(idAndVer, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,4 +14,13 @@ public interface IPackageCacheManager {
|
|||
String getPackageUrl(String packageId) throws IOException;
|
||||
|
||||
NpmPackage loadPackage(String id, String version) throws FHIRException, IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param idAndVer - use id#ver
|
||||
* @return
|
||||
* @throws FHIRException
|
||||
* @throws IOException
|
||||
*/
|
||||
NpmPackage loadPackage(String idAndVer) throws FHIRException, IOException;
|
||||
}
|
||||
|
|
|
@ -114,4 +114,12 @@ public class PackageHacker {
|
|||
}
|
||||
}
|
||||
|
||||
public static String fixPackageUrl(String webref) {
|
||||
// workaround for past publishing problems
|
||||
if (webref.equals("file://C:\\GitHub\\hl7.fhir.us.qicore#4.0.0\\output")) {
|
||||
return "http://hl7.org/fhir/us/qicore/STU4";
|
||||
}
|
||||
return webref;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,12 +2,14 @@ package org.hl7.fhir.utilities.i18n;
|
|||
|
||||
public class I18nConstants {
|
||||
|
||||
|
||||
public static final String ADDING_WRONG_PATH = "Adding_wrong_path";
|
||||
public static final String ADDING_WRONG_PATH_IN_PROFILE___VS_ = "Adding_wrong_path_in_profile___vs_";
|
||||
public static final String ADDING_WRONG_PATH__OUTCOMEGETPATH___RESULTPATHBASE__ = "Adding_wrong_path__outcomegetPath___resultPathBase__";
|
||||
public static final String ALL_OBSERVATIONS_SHOULD_HAVE_AN_EFFECTIVEDATETIME_OR_AN_EFFECTIVEPERIOD = "All_observations_should_have_an_effectiveDateTime_or_an_effectivePeriod";
|
||||
public static final String ALL_OBSERVATIONS_SHOULD_HAVE_A_PERFORMER = "All_observations_should_have_a_performer";
|
||||
public static final String ALL_OBSERVATIONS_SHOULD_HAVE_A_SUBJECT = "All_observations_should_have_a_subject";
|
||||
public static final String ALL_OK = "ALL_OK";
|
||||
public static final String ATTEMPT_TO_A_SLICE_AN_ELEMENT_THAT_DOES_NOT_REPEAT__FROM__IN_ = "Attempt_to_a_slice_an_element_that_does_not_repeat__from__in_";
|
||||
public static final String ATTEMPT_TO_REPLACE_ELEMENT_NAME_FOR_A_NONCHOICE_TYPE = "Attempt_to_replace_element_name_for_a_nonchoice_type";
|
||||
public static final String ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED = "Attempt_to_use_a_snapshot_on_profile__as__before_it_is_generated";
|
||||
|
@ -79,6 +81,7 @@ public class I18nConstants {
|
|||
public static final String ERROR_AT_PATH__SLICE_NAME_MUST_BE__BUT_IS_ = "Error_at_path__Slice_name_must_be__but_is_";
|
||||
public static final String ERROR_AT__THE_TARGET_PROFILE__IS_NOT__VALID_CONSTRAINT_ON_THE_BASE_ = "Error_at__The_target_profile__is_not__valid_constraint_on_the_base_";
|
||||
public static final String ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES = "Error_expanding_ValueSet_running_without_terminology_services";
|
||||
public static final String ERROR_GENERATING_SNAPSHOT = "ERROR_GENERATING_SNAPSHOT";
|
||||
public static final String ERROR_GENERATING_TABLE_FOR_PROFILE__ = "Error_generating_table_for_profile__";
|
||||
public static final String ERROR_IN_PROFILE__AT__BASE_ISSUMMARY___DERIVED_ISSUMMARY__ = "Error_in_profile__at__Base_isSummary___derived_isSummary__";
|
||||
public static final String ERROR_PARSING_ = "Error_parsing_";
|
||||
|
@ -103,7 +106,6 @@ public class I18nConstants {
|
|||
public static final String EXTENSION_EXT_SIMPLE = "Extension_EXT_Simple";
|
||||
public static final String EXTENSION_EXT_SUBEXTENSION_INVALID = "Extension_EXT_SubExtension_Invalid";
|
||||
public static final String EXTENSION_EXT_TYPE = "Extension_EXT_Type";
|
||||
public static final String EXTENSION_PROF_TYPE = "Extension_PROF_Type";
|
||||
public static final String EXTENSION_EXT_UNKNOWN = "Extension_EXT_Unknown";
|
||||
public static final String EXTENSION_EXT_UNKNOWN_NOTHERE = "Extension_EXT_Unknown_NotHere";
|
||||
public static final String EXTENSION_EXT_URL_ABSOLUTE = "Extension_EXT_URL_Absolute";
|
||||
|
@ -112,6 +114,50 @@ public class I18nConstants {
|
|||
public static final String EXTENSION_EXT_VERSION_INVALID = "Extension_EXT_Version_Invalid";
|
||||
public static final String EXTENSION_EXT_VERSION_INVALIDID = "Extension_EXT_Version_InvalidId";
|
||||
public static final String EXTENSION_EXT_VERSION_NOCHANGE = "Extension_EXT_Version_NoChange";
|
||||
public static final String EXTENSION_PROF_TYPE = "Extension_PROF_Type";
|
||||
public static final String FHIRPATH_ALIAS_COLLECTION = "FHIRPATH_ALIAS_COLLECTION";
|
||||
public static final String FHIRPATH_CANNOT_USE = "FHIRPATH_CANNOT_USE";
|
||||
public static final String FHIRPATH_CANT_COMPARE = "FHIRPATH_CANT_COMPARE";
|
||||
public static final String FHIRPATH_CHECK_FAILED = "FHIRPATH_CHECK_FAILED";
|
||||
public static final String FHIRPATH_CODED_ONLY = "FHIRPATH_CODED_ONLY";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_NAME = "FHIRPATH_DISCRIMINATOR_BAD_NAME";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_CONST = "FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_CONST";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_GROUP = "FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_GROUP";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_CANT_FIND = "FHIRPATH_DISCRIMINATOR_CANT_FIND";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_MULTIPLE_PROFILES = "FHIRPATH_DISCRIMINATOR_MULTIPLE_PROFILES";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_MULTIPLE_TYPES = "FHIRPATH_DISCRIMINATOR_MULTIPLE_TYPES";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_NAME_ALREADY_SLICED = "FHIRPATH_DISCRIMINATOR_NAME_ALREADY_SLICED";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_NOTYPE = "FHIRPATH_DISCRIMINATOR_NOTYPE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_NO_CODE = "FHIRPATH_DISCRIMINATOR_NO_CODE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_RESOLVE_MULTIPLE_TYPES = "FHIRPATH_DISCRIMINATOR_RESOLVE_MULTIPLE_TYPES";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_RESOLVE_NOT_REFERENCE = "FHIRPATH_DISCRIMINATOR_RESOLVE_NOT_REFERENCE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_RESOLVE_NO_TYPE = "FHIRPATH_DISCRIMINATOR_RESOLVE_NO_TYPE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND = "FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_TYPE_MULTIPLE = "FHIRPATH_DISCRIMINATOR_TYPE_MULTIPLE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_TYPE_NONE = "FHIRPATH_DISCRIMINATOR_TYPE_NONE";
|
||||
public static final String FHIRPATH_HO_HOST_SERVICES = "FHIRPATH_HO_HOST_SERVICES";
|
||||
public static final String FHIRPATH_LEFT_VALUE_PLURAL = "FHIRPATH_LEFT_VALUE_PLURAL";
|
||||
public static final String FHIRPATH_LEFT_VALUE_WRONG_TYPE = "FHIRPATH_LEFT_VALUE_WRONG_TYPE";
|
||||
public static final String FHIRPATH_LOCATION = "FHIRPATH_LOCATION";
|
||||
public static final String FHIRPATH_NOT_IMPLEMENTED = "FHIRPATH_NOT_IMPLEMENTED";
|
||||
public static final String FHIRPATH_NO_COLLECTION = "FHIRPATH_NO_COLLECTION";
|
||||
public static final String FHIRPATH_NO_TYPE = "FHIRPATH_NO_TYPE";
|
||||
public static final String FHIRPATH_OP_INCOMPATIBLE = "FHIRPATH_OP_INCOMPATIBLE";
|
||||
public static final String FHIRPATH_ORDERED_ONLY = "FHIRPATH_ORDERED_ONLY";
|
||||
public static final String FHIRPATH_PARAM_WRONG = "FHIRPATH_PARAM_WRONG";
|
||||
public static final String FHIRPATH_PRIMITIVE_ONLY = "FHIRPATH_PRIMITIVE_ONLY";
|
||||
public static final String FHIRPATH_REFERENCE_ONLY = "FHIRPATH_ORDERED_ONLY";
|
||||
public static final String FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND = "FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND";
|
||||
public static final String FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET = "FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET";
|
||||
public static final String FHIRPATH_RIGHT_VALUE_PLURAL = "FHIRPATH_RIGHT_VALUE_PLURAL";
|
||||
public static final String FHIRPATH_RIGHT_VALUE_WRONG_TYPE = "FHIRPATH_RIGHT_VALUE_WRONG_TYPE";
|
||||
public static final String FHIRPATH_STRING_ONLY = "FHIRPATH_STRING_ONLY";
|
||||
public static final String FHIRPATH_UNABLE_BOOLEAN = "FHIRPATH_UNABLE_BOOLEAN";
|
||||
public static final String FHIRPATH_UNKNOWN_CONSTANT = "FHIRPATH_UNKNOWN_CONSTANT";
|
||||
public static final String FHIRPATH_UNKNOWN_CONTEXT = "FHIRPATH_UNKNOWN_CONTEXT";
|
||||
public static final String FHIRPATH_UNKNOWN_CONTEXT_ELEMENT = "FHIRPATH_UNKNOWN_CONTEXT_ELEMENT";
|
||||
public static final String FHIRPATH_UNKNOWN_NAME = "FHIRPATH_UNWKNOWN_NAME";
|
||||
public static final String FHIRPATH_WRONG_PARAM_TYPE = "FHIRPATH_WRONG_PARAM_TYPE";
|
||||
public static final String FIXED_TYPE_CHECKS_DT_ADDRESS_LINE = "Fixed_Type_Checks_DT_Address_Line";
|
||||
public static final String FIXED_TYPE_CHECKS_DT_NAME_FAMILY = "Fixed_Type_Checks_DT_Name_Family";
|
||||
public static final String FIXED_TYPE_CHECKS_DT_NAME_GIVEN = "Fixed_Type_Checks_DT_Name_Given";
|
||||
|
@ -125,8 +171,8 @@ public class I18nConstants {
|
|||
public static final String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_EXCEEDS_64_CHARS_IN_LENGTH = "Illegal_path__in_differential_in__name_portion_exceeds_64_chars_in_length";
|
||||
public static final String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NAME_PORTION_MISING_ = "Illegal_path__in_differential_in__name_portion_mising_";
|
||||
public static final String ILLEGAL_PATH__IN_DIFFERENTIAL_IN__NO_UNICODE_WHITESPACE = "Illegal_path__in_differential_in__no_unicode_whitespace";
|
||||
public static final String INTERNAL_ERROR___TYPE_NOT_KNOWN_ = "Internal_error___type_not_known_";
|
||||
public static final String INTERNAL_ERROR = "Internal_error";
|
||||
public static final String INTERNAL_ERROR___TYPE_NOT_KNOWN_ = "Internal_error___type_not_known_";
|
||||
public static final String INTERNAL_INT_BAD_TYPE = "Internal_INT_Bad_Type";
|
||||
public static final String INTERNAL_RECURSION_DETECTION_FIND_LOOP_PATH_RECURSION____CHECK_PATHS_ARE_VALID_FOR_PATH_ = "Internal_recursion_detection_find_loop_path_recursion____check_paths_are_valid_for_path_";
|
||||
public static final String INVALID_SLICING__THERE_IS_MORE_THAN_ONE_TYPE_SLICE_AT__BUT_ONE_OF_THEM__HAS_MIN__1_SO_THE_OTHER_SLICES_CANNOT_EXIST = "Invalid_slicing__there_is_more_than_one_type_slice_at__but_one_of_them__has_min__1_so_the_other_slices_cannot_exist";
|
||||
|
@ -210,6 +256,7 @@ public class I18nConstants {
|
|||
public static final String NO_VALUE_SET_IN_URL = "no_value_set";
|
||||
public static final String NULL_MIN = "null_min";
|
||||
public static final String OBJECT_MUST_HAVE_SOME_CONTENT = "Object_must_have_some_content";
|
||||
public static final String PACKAGE_VERSION_MISMATCH = "PACKAGE_VERSION_MISMATCH";
|
||||
public static final String PARSER_TYPE__NOT_SUPPORTED = "Parser_Type__not_supported";
|
||||
public static final String PROBLEM_EVALUATING_SLICING_EXPRESSION_FOR_ELEMENT_IN_PROFILE__PATH__FHIRPATH___ = "Problem_evaluating_slicing_expression_for_element_in_profile__path__fhirPath___";
|
||||
public static final String PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__ = "Problem_processing_expression__in_profile__path__";
|
||||
|
@ -286,12 +333,17 @@ public class I18nConstants {
|
|||
public static final String RESOURCE_RES_ID_PROHIBITED = "Resource_RES_ID_Prohibited";
|
||||
public static final String RESOURCE_TYPE_MISMATCH_FOR___ = "Resource_type_mismatch_for___";
|
||||
public static final String SAME_ID_ON_MULTIPLE_ELEMENTS__IN_ = "Same_id_on_multiple_elements__in_";
|
||||
public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG";
|
||||
public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG";
|
||||
public static final String SEARCHPARAMETER_NOTFOUND = "SEARCHPARAMETER_NOTFOUND";
|
||||
public static final String SEARCHPARAMETER_TYPE_WRONG = "SEARCHPARAMETER_TYPE_WRONG";
|
||||
public static final String SECURITY_STRING_CONTENT_ERROR = "SECURITY_STRING_CONTENT_ERROR";
|
||||
public static final String SECURITY_STRING_CONTENT_WARNING = "SECURITY_STRING_CONTENT_WARNING";
|
||||
public static final String SLICE_ENCOUNTERED_MIDWAY_THROUGH_SET_PATH___ID___ = "Slice_encountered_midway_through_set_path___id___";
|
||||
public static final String SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___DISCIMINATOR___ = "Slicing_rules_on_differential__do_not_match_those_on_base___disciminator___";
|
||||
public static final String SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___ORDER___ = "Slicing_rules_on_differential__do_not_match_those_on_base___order___";
|
||||
public static final String SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___RULE___ = "Slicing_rules_on_differential__do_not_match_those_on_base___rule___";
|
||||
public static final String SNAPSHOT_EXISTING_PROBLEM = "SNAPSHOT_EXISTING_PROBLEM";
|
||||
public static final String STRUCTUREDEFINITION__AT__ILLEGAL_CONSTRAINED_TYPE__FROM__IN_ = "StructureDefinition__at__illegal_constrained_type__from__in_";
|
||||
public static final String TERMINOLOGY_PASSTHROUGH_TX_MESSAGE = "Terminology_PassThrough_TX_Message";
|
||||
public static final String TERMINOLOGY_TX_BINDING_CANTCHECK = "Terminology_TX_Binding_CantCheck";
|
||||
|
@ -360,6 +412,10 @@ public class I18nConstants {
|
|||
public static final String THIS_PROPERTY_MUST_BE_A_URI_OR_BNODE_NOT_A_ = "This_property_must_be_a_URI_or_bnode_not_a_";
|
||||
public static final String THIS_PROPERTY_MUST_BE__NOT_ = "This_property_must_be__not_";
|
||||
public static final String THIS__CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAMESPACE = "This__cannot_be_parsed_as_a_FHIR_object_no_namespace";
|
||||
public static final String TYPE_CHECKS_FIXED_CC = "TYPE_CHECKS_FIXED_CC";
|
||||
public static final String TYPE_CHECKS_FIXED_CC_US = "TYPE_CHECKS_FIXED_CC_US";
|
||||
public static final String TYPE_CHECKS_PATTERN_CC = "TYPE_CHECKS_PATTERN_CC";
|
||||
public static final String TYPE_CHECKS_PATTERN_CC_US = "TYPE_CHECKS_PATTERN_CC_US";
|
||||
public static final String TYPE_ON_FIRST_DIFFERENTIAL_ELEMENT = "type_on_first_differential_element";
|
||||
public static final String TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_ = "type_on_first_snapshot_element_for__in__from_";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE = "TYPE_SPECIFIC_CHECKS_CANONICAL_ABSOLUTE";
|
||||
|
@ -466,6 +522,7 @@ public class I18nConstants {
|
|||
public static final String UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT = "Unxpected_internal_condition__no_source_on_diff_element";
|
||||
public static final String VALIDATION_BUNDLE_MESSAGE = "Validation_BUNDLE_Message";
|
||||
public static final String VALIDATION_VAL_CONTENT_UNKNOWN = "Validation_VAL_Content_Unknown";
|
||||
public static final String VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN = "VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN";
|
||||
public static final String VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT = "VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT";
|
||||
public static final String VALIDATION_VAL_NOTYPE = "Validation_VAL_NoType";
|
||||
public static final String VALIDATION_VAL_PROFILE_MATCHMULTIPLE = "Validation_VAL_Profile_MatchMultiple";
|
||||
|
@ -481,12 +538,21 @@ public class I18nConstants {
|
|||
public static final String VALIDATION_VAL_PROFILE_NOTSLICE = "Validation_VAL_Profile_NotSlice";
|
||||
public static final String VALIDATION_VAL_PROFILE_NOTYPE = "Validation_VAL_Profile_NoType";
|
||||
public static final String VALIDATION_VAL_PROFILE_OUTOFORDER = "Validation_VAL_Profile_OutOfOrder";
|
||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST = "VALIDATION_VAL_PROFILE_SIGNPOST";
|
||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = "VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL";
|
||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_META = "VALIDATION_VAL_PROFILE_SIGNPOST_META";
|
||||
public static final String VALIDATION_VAL_PROFILE_SLICEORDER = "Validation_VAL_Profile_SliceOrder";
|
||||
public static final String VALIDATION_VAL_PROFILE_UNKNOWN = "Validation_VAL_Profile_Unknown";
|
||||
public static final String VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN = "VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN";
|
||||
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE = "Validation_VAL_Profile_WrongType";
|
||||
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE2 = "Validation_VAL_Profile_WrongType2";
|
||||
public static final String VALIDATION_VAL_UNKNOWN_PROFILE = "Validation_VAL_Unknown_Profile";
|
||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE";
|
||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER";
|
||||
public static final String VALUESET_NO_SYSTEM_WARNING = "VALUESET_NO_SYSTEM_WARNING";
|
||||
public static final String VALUESET_REFERENCE_INVALID_TYPE = "VALUESET_REFERENCE_INVALID_TYPE";
|
||||
public static final String VALUESET_REFERENCE_UNKNOWN = "VALUESET_REFERENCE_UNKNOWN";
|
||||
public static final String VALUESET_UNC_SYSTEM_WARNING = "VALUESET_UNC_SYSTEM_WARNING";
|
||||
public static final String VALUESET_UNC_SYSTEM_WARNING_VER = "VALUESET_UNC_SYSTEM_WARNING_VER";
|
||||
public static final String VERSION_MISMATCH_THE_CONTEXT_HAS_VERSION__LOADED_AND_THE_NEW_CONTENT_BEING_LOADED_IS_VERSION_ = "Version_mismatch_The_context_has_version__loaded_and_the_new_content_being_loaded_is_version_";
|
||||
public static final String WRONG_NAMESPACE__EXPECTED_ = "Wrong_namespace__expected_";
|
||||
public static final String WRONG_TYPE_FOR_RESOURCE = "Wrong_type_for_resource";
|
||||
|
@ -494,6 +560,7 @@ public class I18nConstants {
|
|||
public static final String XHTML_URL_INVALID = "XHTML_URL_INVALID";
|
||||
public static final String XHTML_URL_INVALID_CHARS = "XHTML_URL_INVALID_CHARS";
|
||||
public static final String XHTML_XHTML_ATTRIBUTE_ILLEGAL = "XHTML_XHTML_Attribute_Illegal";
|
||||
public static final String XHTML_XHTML_DOCTYPE_ILLEGAL = "XHTML_XHTML_DOCTYPE_ILLEGAL";
|
||||
public static final String XHTML_XHTML_ELEMENT_ILLEGAL = "XHTML_XHTML_Element_Illegal";
|
||||
public static final String XHTML_XHTML_NAME_INVALID = "XHTML_XHTML_Name_Invalid";
|
||||
public static final String XHTML_XHTML_NS_INVALID = "XHTML_XHTML_NS_InValid";
|
||||
|
@ -504,68 +571,5 @@ public class I18nConstants {
|
|||
public static final String _HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_ = "_has_children__and_multiple_types__in_profile_";
|
||||
public static final String _HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE = "_has_children__for_type__in_profile__but_cant_find_type";
|
||||
public static final String _HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_ = "_has_no_children__and_no_types_in_profile_";
|
||||
public static final String ALL_OK = "ALL_OK";
|
||||
public static final String SEARCHPARAMETER_NOTFOUND = "SEARCHPARAMETER_NOTFOUND";
|
||||
public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG";
|
||||
public static final String SEARCHPARAMETER_TYPE_WRONG = "SEARCHPARAMETER_TYPE_WRONG";
|
||||
public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG";
|
||||
public static final String VALUESET_NO_SYSTEM_WARNING = "VALUESET_NO_SYSTEM_WARNING";
|
||||
public static final String VALUESET_UNC_SYSTEM_WARNING = "VALUESET_UNC_SYSTEM_WARNING";
|
||||
public static final String VALUESET_UNC_SYSTEM_WARNING_VER = "VALUESET_UNC_SYSTEM_WARNING_VER";
|
||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE";
|
||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER";
|
||||
public static final String TYPE_CHECKS_PATTERN_CC = "TYPE_CHECKS_PATTERN_CC";
|
||||
public static final String TYPE_CHECKS_PATTERN_CC_US = "TYPE_CHECKS_PATTERN_CC_US";
|
||||
public static final String TYPE_CHECKS_FIXED_CC = "TYPE_CHECKS_FIXED_CC";
|
||||
public static final String TYPE_CHECKS_FIXED_CC_US = "TYPE_CHECKS_FIXED_CC_US";
|
||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST = "VALIDATION_VAL_PROFILE_SIGNPOST";
|
||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_META = "VALIDATION_VAL_PROFILE_SIGNPOST_META";
|
||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = "VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL";
|
||||
public static final String ERROR_GENERATING_SNAPSHOT = "ERROR_GENERATING_SNAPSHOT";
|
||||
public static final String SNAPSHOT_EXISTING_PROBLEM = "SNAPSHOT_EXISTING_PROBLEM";
|
||||
public static final String FHIRPATH_LOCATION = "FHIRPATH_LOCATION";
|
||||
public static final String FHIRPATH_UNKNOWN_CONTEXT = "FHIRPATH_UNKNOWN_CONTEXT";
|
||||
public static final String FHIRPATH_UNKNOWN_CONTEXT_ELEMENT = "FHIRPATH_UNKNOWN_CONTEXT_ELEMENT";
|
||||
public static final String FHIRPATH_ALIAS_COLLECTION = "FHIRPATH_ALIAS_COLLECTION";
|
||||
public static final String FHIRPATH_UNKNOWN_NAME = "FHIRPATH_UNWKNOWN_NAME";
|
||||
public static final String FHIRPATH_UNKNOWN_CONSTANT = "FHIRPATH_UNKNOWN_CONSTANT";
|
||||
public static final String FHIRPATH_CANNOT_USE = "FHIRPATH_CANNOT_USE";
|
||||
public static final String FHIRPATH_CANT_COMPARE = "FHIRPATH_CANT_COMPARE";
|
||||
public static final String FHIRPATH_LEFT_VALUE_PLURAL = "FHIRPATH_LEFT_VALUE_PLURAL";
|
||||
public static final String FHIRPATH_LEFT_VALUE_WRONG_TYPE = "FHIRPATH_LEFT_VALUE_WRONG_TYPE";
|
||||
public static final String FHIRPATH_RIGHT_VALUE_PLURAL = "FHIRPATH_RIGHT_VALUE_PLURAL";
|
||||
public static final String FHIRPATH_RIGHT_VALUE_WRONG_TYPE = "FHIRPATH_RIGHT_VALUE_WRONG_TYPE";
|
||||
public static final String FHIRPATH_OP_INCOMPATIBLE = "FHIRPATH_OP_INCOMPATIBLE";
|
||||
public static final String FHIRPATH_HO_HOST_SERVICES = "FHIRPATH_HO_HOST_SERVICES";
|
||||
public static final String FHIRPATH_WRONG_PARAM_TYPE = "FHIRPATH_WRONG_PARAM_TYPE";
|
||||
public static final String FHIRPATH_ORDERED_ONLY = "FHIRPATH_ORDERED_ONLY";
|
||||
public static final String FHIRPATH_REFERENCE_ONLY = "FHIRPATH_ORDERED_ONLY";
|
||||
public static final String FHIRPATH_CODED_ONLY = "FHIRPATH_CODED_ONLY";
|
||||
public static final String FHIRPATH_STRING_ONLY = "FHIRPATH_STRING_ONLY";
|
||||
public static final String FHIRPATH_PRIMITIVE_ONLY = "FHIRPATH_PRIMITIVE_ONLY";
|
||||
public static final String FHIRPATH_NO_COLLECTION = "FHIRPATH_NO_COLLECTION";
|
||||
public static final String FHIRPATH_NOT_IMPLEMENTED = "FHIRPATH_NOT_IMPLEMENTED";
|
||||
public static final String FHIRPATH_PARAM_WRONG = "FHIRPATH_PARAM_WRONG";
|
||||
public static final String FHIRPATH_CHECK_FAILED = "FHIRPATH_CHECK_FAILED";
|
||||
public static final String FHIRPATH_NO_TYPE = "FHIRPATH_NO_TYPE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_NAME_ALREADY_SLICED = "FHIRPATH_DISCRIMINATOR_NAME_ALREADY_SLICED";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND = "FHIRPATH_DISCRIMINATOR_THIS_CANNOT_FIND";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_RESOLVE_NO_TYPE = "FHIRPATH_DISCRIMINATOR_RESOLVE_NO_TYPE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_RESOLVE_MULTIPLE_TYPES = "FHIRPATH_DISCRIMINATOR_RESOLVE_MULTIPLE_TYPES";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_RESOLVE_NOT_REFERENCE = "FHIRPATH_DISCRIMINATOR_RESOLVE_NOT_REFERENCE";
|
||||
public static final String FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET = "FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET";
|
||||
public static final String FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND = "FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_TYPE_NONE = "FHIRPATH_DISCRIMINATOR_TYPE_NONE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_TYPE_MULTIPLE = "FHIRPATH_DISCRIMINATOR_TYPE_MULTIPLE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_NO_CODE = "FHIRPATH_DISCRIMINATOR_NO_CODE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_NAME = "FHIRPATH_DISCRIMINATOR_BAD_NAME";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_GROUP = "FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_GROUP";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_CONST = "FHIRPATH_DISCRIMINATOR_BAD_SYNTAX_CONST";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_CANT_FIND = "FHIRPATH_DISCRIMINATOR_CANT_FIND";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_NOTYPE = "FHIRPATH_DISCRIMINATOR_NOTYPE";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_MULTIPLE_TYPES = "FHIRPATH_DISCRIMINATOR_MULTIPLE_TYPES";
|
||||
public static final String FHIRPATH_DISCRIMINATOR_MULTIPLE_PROFILES = "FHIRPATH_DISCRIMINATOR_MULTIPLE_PROFILES";
|
||||
public static final String FHIRPATH_UNABLE_BOOLEAN = "FHIRPATH_UNABLE_BOOLEAN";
|
||||
public static final String XHTML_XHTML_DOCTYPE_ILLEGAL = "XHTML_XHTML_DOCTYPE_ILLEGAL";
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
package org.hl7.fhir.utilities.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -128,4 +133,10 @@ public class JSONUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static JsonObject fetchJson(String source) throws IOException {
|
||||
URL url = new URL(source);
|
||||
URLConnection c = url.openConnection();
|
||||
return (JsonObject) new com.google.gson.JsonParser().parse(TextFile.streamToString(c.getInputStream()));
|
||||
}
|
||||
|
||||
}
|
|
@ -147,7 +147,7 @@ Terminology_TX_NoValid_1 = None of the codes provided are in the value set {0} (
|
|||
Terminology_TX_NoValid_10 = The code provided is not in the maximum value set {0} ({1}), and a code from this value set is required) (code = {2}#{3})
|
||||
Terminology_TX_NoValid_11 = The code provided is not in the maximum value set {0} ({1}{2})
|
||||
Terminology_TX_NoValid_12 = The Coding provided is not in the value set {0}, and a code is required from this value set. {1}
|
||||
Terminology_TX_NoValid_13 = The Coding provided is not in the value set {0}, and a code should come from this value set unless it has no suitable code. {1}
|
||||
Terminology_TX_NoValid_13 = The Coding provided ({2}) is not in the value set {0}, and a code should come from this value set unless it has no suitable code. {1}
|
||||
Terminology_TX_NoValid_14 = The Coding provided is not in the value set {0}, and a code is recommended to come from this value set. {1}
|
||||
Terminology_TX_NoValid_15 = The value provided ("{0}") could not be validated in the absence of a terminology server
|
||||
Terminology_TX_NoValid_16 = The value provided ("{0}") is not in the value set {1} ({2}), and a code is required from this value set){3}
|
||||
|
@ -567,4 +567,6 @@ FHIRPATH_DISCRIMINATOR_MULTIPLE_TYPES = Error in discriminator at {0}: no childr
|
|||
FHIRPATH_DISCRIMINATOR_MULTIPLE_PROFILES = Error in discriminator at {0}: no children, multiple type profiles
|
||||
FHIRPATH_UNABLE_BOOLEAN = Unable to evaluate as a boolean: {0}
|
||||
XHTML_XHTML_DOCTYPE_ILLEGAL = Malformed XHTML: Found a DocType declaration, and these are not allowed (XXE security vulnerability protection)
|
||||
|
||||
PACKAGE_VERSION_MISMATCH = FHIR Version mismatch in package {0}: version is {2} but must be {1} (path: {3})
|
||||
VALUESET_REFERENCE_UNKNOWN = The value set import {0} could not be found so cannot be checked
|
||||
VALUESET_REFERENCE_INVALID_TYPE = The value set import {0} points to a resource of type {1} which is not valid
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.cache.PackageClient;
|
||||
import org.hl7.fhir.utilities.cache.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
import org.hl7.fhir.utilities.i18n.I18nBase;
|
||||
|
@ -770,7 +771,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
|||
}
|
||||
|
||||
public void loadIg(String src, boolean recursive) throws IOException, FHIRException, Exception {
|
||||
NpmPackage npm = pcm.loadPackage(src, null);
|
||||
NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_REGEX) ? pcm.loadPackage(src, null) : null;
|
||||
if (npm != null) {
|
||||
for (String s : npm.dependencies()) {
|
||||
if (!context.getLoadedPackages().contains(s)) {
|
||||
|
|
|
@ -239,27 +239,30 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (c.getAppContext() instanceof Element) {
|
||||
Element bnd = (Element) c.getAppContext();
|
||||
Base res = resolveInBundle(url, bnd);
|
||||
if (res != null)
|
||||
if (res != null) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
Base res = resolveInBundle(url, c.getResource());
|
||||
if (res != null)
|
||||
if (res != null) {
|
||||
return res;
|
||||
}
|
||||
res = resolveInBundle(url, c.getContainer());
|
||||
if (res != null)
|
||||
if (res != null) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (externalHostServices != null)
|
||||
if (externalHostServices != null) {
|
||||
return externalHostServices.resolveReference(c.getAppContext(), url, refContext);
|
||||
else if (fetcher != null)
|
||||
} else if (fetcher != null) {
|
||||
try {
|
||||
return fetcher.fetch(c.getAppContext(), url);
|
||||
} catch (IOException e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
throw new Error(context.formatMessage(I18nConstants.NOT_DONE_YET__RESOLVE__LOCALLY_2, url));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1368,7 +1371,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c, stack);
|
||||
else
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_13, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()));
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_13, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()), gen(c));
|
||||
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
||||
if (baseOnly) {
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_14, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()));
|
||||
|
@ -1392,6 +1395,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
|
||||
private String gen(Coding c) {
|
||||
return c.getSystem()+"#"+c.getCode()+ (c.hasDisplay() ? " \""+c.getDisplay()+"\"" : "");
|
||||
}
|
||||
|
||||
private boolean isValueSet(String url) {
|
||||
try {
|
||||
ValueSet vs = context.fetchResourceWithException(ValueSet.class, url);
|
||||
|
@ -1633,6 +1640,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if ("http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version".equals(extUrl)) {
|
||||
list.get(0).setExpression("Element"); // well, it can't be used anywhere but the list of places it can be used is quite long
|
||||
}
|
||||
if (!VersionUtilities.isThisOrLater("4.6", context.getVersion())) {
|
||||
if (Utilities.existsInList(extUrl, "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation", "http://hl7.org/fhir/StructureDefinition/capabilitystatement-prohibited")) {
|
||||
list.get(0).setExpression("Element"); // well, they can't be used anywhere but the list of places they can be used is quite long
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,13 @@ package org.hl7.fhir.validation.instance.type;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
|
@ -56,6 +59,23 @@ public class ValueSetValidator extends BaseValidator {
|
|||
String system = include.getChildValue("system");
|
||||
String version = include.getChildValue("version");
|
||||
boolean systemOk = true;
|
||||
List<Element> valuesets = include.getChildrenByName("valueSet");
|
||||
int i = 0;
|
||||
for (Element ve : valuesets) {
|
||||
String v = ve.getValue();
|
||||
ValueSet vs = context.fetchResource(ValueSet.class, v);
|
||||
if (vs == null) {
|
||||
NodeStack ns = stack.push(ve, i, ve.getProperty().getDefinition(), ve.getProperty().getDefinition());
|
||||
|
||||
Resource rs = context.fetchResource(Resource.class, v);
|
||||
if (rs != null) {
|
||||
warning(errors, IssueType.BUSINESSRULE, ns.getLiteralPath(), false, I18nConstants.VALUESET_REFERENCE_INVALID_TYPE, v, rs.fhirType());
|
||||
} else {
|
||||
warning(errors, IssueType.BUSINESSRULE, ns.getLiteralPath(), false, I18nConstants.VALUESET_REFERENCE_UNKNOWN, v);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
List<Element> concepts = include.getChildrenByName("concept");
|
||||
List<Element> filters = include.getChildrenByName("filter");
|
||||
if (!Utilities.noString(system)) {
|
||||
|
|
|
@ -116,7 +116,7 @@ public class ComparisonTests {
|
|||
CanonicalResource left = load("left");
|
||||
CanonicalResource right = load("right");
|
||||
|
||||
ComparisonSession session = new ComparisonSession(context, "Comparison Tests", null);
|
||||
ComparisonSession session = new ComparisonSession(context, context, "Comparison Tests", null);
|
||||
|
||||
if (left instanceof CodeSystem && right instanceof CodeSystem) {
|
||||
CodeSystemComparer cs = new CodeSystemComparer(session);
|
||||
|
@ -146,7 +146,7 @@ public class ComparisonTests {
|
|||
ProfileUtilities utils = new ProfileUtilities(context, null, null);
|
||||
genSnapshot(utils, (StructureDefinition) left);
|
||||
genSnapshot(utils, (StructureDefinition) right);
|
||||
ProfileComparer pc = new ProfileComparer(session, utils);
|
||||
ProfileComparer pc = new ProfileComparer(session, utils, utils);
|
||||
ProfileComparison csc = pc.compare((StructureDefinition) left, (StructureDefinition) right);
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-union.json")), csc.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-intersection.json")), csc.getIntersection());
|
||||
|
|
|
@ -213,7 +213,7 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
|
|||
else
|
||||
val.validate(null, errors, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.XML);
|
||||
System.out.println(val.reportTimes());
|
||||
checkOutcomes(errors, content);
|
||||
checkOutcomes(errors, content, null);
|
||||
if (content.has("profile")) {
|
||||
System.out.print("** Profile: ");
|
||||
JsonObject profile = content.getAsJsonObject("profile");
|
||||
|
@ -244,7 +244,7 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
|
|||
else
|
||||
val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.XML, asSdList(sd));
|
||||
System.out.println(val.reportTimes());
|
||||
checkOutcomes(errorsProfile, profile);
|
||||
checkOutcomes(errorsProfile, profile, filename);
|
||||
}
|
||||
if (content.has("logical")) {
|
||||
JsonObject logical = content.getAsJsonObject("logical");
|
||||
|
@ -268,7 +268,7 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
|
|||
Assert.assertTrue(fp.evaluateToBoolean(null, le, le, le, fp.parse(exp)));
|
||||
}
|
||||
}
|
||||
checkOutcomes(errorsLogical, logical);
|
||||
checkOutcomes(errorsLogical, logical, "logical");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,7 +330,7 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
|
|||
}
|
||||
}
|
||||
|
||||
private void checkOutcomes(List<ValidationMessage> errors, JsonObject focus) {
|
||||
private void checkOutcomes(List<ValidationMessage> errors, JsonObject focus, String profile) {
|
||||
JsonObject java = focus.getAsJsonObject("java");
|
||||
int ec = 0;
|
||||
int wc = 0;
|
||||
|
@ -358,11 +358,11 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
|
|||
}
|
||||
}
|
||||
if (!TestingUtilities.context(version).isNoTerminologyServer() || !focus.has("tx-dependent")) {
|
||||
Assert.assertEquals("Test " + name + ": Expected " + Integer.toString(java.get("errorCount").getAsInt()) + " errors, but found " + Integer.toString(ec) + ".", java.get("errorCount").getAsInt(), ec);
|
||||
Assert.assertEquals("Test " + name + (profile == null ? "" : " profile: "+ profile) + ": Expected " + Integer.toString(java.get("errorCount").getAsInt()) + " errors, but found " + Integer.toString(ec) + ".", java.get("errorCount").getAsInt(), ec);
|
||||
if (java.has("warningCount"))
|
||||
Assert.assertEquals( "Test " + name + ": Expected " + Integer.toString(java.get("warningCount").getAsInt()) + " warnings, but found " + Integer.toString(wc) + ".", java.get("warningCount").getAsInt(), wc);
|
||||
Assert.assertEquals( "Test " + name + (profile == null ? "" : " profile: "+ profile) + ": Expected " + Integer.toString(java.get("warningCount").getAsInt()) + " warnings, but found " + Integer.toString(wc) + ".", java.get("warningCount").getAsInt(), wc);
|
||||
if (java.has("infoCount"))
|
||||
Assert.assertEquals( "Test " + name + ": Expected " + Integer.toString(java.get("infoCount").getAsInt()) + " hints, but found " + Integer.toString(hc) + ".", java.get("infoCount").getAsInt(), hc);
|
||||
Assert.assertEquals( "Test " + name + (profile == null ? "" : " profile: "+ profile) + ": Expected " + Integer.toString(java.get("infoCount").getAsInt()) + " hints, but found " + Integer.toString(hc) + ".", java.get("infoCount").getAsInt(), hc);
|
||||
}
|
||||
if (java.has("error-locations")) {
|
||||
JsonArray el = java.getAsJsonArray("error-locations");
|
||||
|
|
Loading…
Reference in New Issue