Merge pull request #1179 from hapifhir/gg-202303-various-fixes
Gg 202303 various fixes
This commit is contained in:
commit
102fc366dd
|
@ -24,6 +24,7 @@ import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
|||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
|
@ -40,6 +41,7 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
|
|||
@Getter @Setter protected boolean killPrimitives;
|
||||
@Getter protected List<String> types = new ArrayList<>();
|
||||
protected ILoaderKnowledgeProviderR5 lkp;
|
||||
private boolean loadProfiles = true;
|
||||
|
||||
public BaseLoaderR5(List<String> types, ILoaderKnowledgeProviderR5 lkp) {
|
||||
super();
|
||||
|
@ -169,6 +171,12 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
|
|||
String url = URL_BASE+versionString()+"/StructureDefinition/"+code;
|
||||
ToolingExtensions.setUrlExtension(tr, ToolingExtensions.EXT_FHIR_TYPE, url);
|
||||
}
|
||||
for (CanonicalType c : tr.getProfile()) {
|
||||
c.setValue(patchUrl(c.getValue(), "StructureDefinition"));
|
||||
}
|
||||
for (CanonicalType c : tr.getTargetProfile()) {
|
||||
c.setValue(patchUrl(c.getValue(), "StructureDefinition"));
|
||||
}
|
||||
}
|
||||
if (ed.hasBinding()) {
|
||||
ed.getBinding().setValueSet(patchUrl(ed.getBinding().getValueSet(), "ValueSet"));
|
||||
|
@ -178,4 +186,20 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public IContextResourceLoader setLoadProfiles(boolean value) {
|
||||
loadProfiles = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean wantLoad(NpmPackage pi, PackageResourceInformation pri) {
|
||||
if (pri.getResourceType().equals("StructureDefinition")) {
|
||||
if (loadProfiles) {
|
||||
return true;
|
||||
} else {
|
||||
return pi.isCore() && Utilities.tail(pri.getUrl()).equals(pri.getStatedType());
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -661,10 +661,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
System.out.println(" "+ed.getId()+" = "+ed.getPath()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
|
||||
}
|
||||
}
|
||||
if (exception)
|
||||
throw new DefinitionException(msg);
|
||||
else
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
||||
handleError(url, msg);
|
||||
}
|
||||
// hack around a problem in R4 definitions (somewhere?)
|
||||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||
|
@ -712,14 +709,20 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
|
||||
wt = "OperationOutcome";
|
||||
}
|
||||
if (!sd.getType().equals(wt)) {
|
||||
boolean ok = isCompatibleType(wt, sd);
|
||||
String tt = sd.getType();
|
||||
boolean elementProfile = u.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT);
|
||||
if (elementProfile) {
|
||||
ElementDefinition edt = sd.getSnapshot().getElementById(u.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT));
|
||||
if (edt == null) {
|
||||
handleError(url, "The profile "+u.getValue()+" has type "+sd.getType()+" which is not consistent with the stated type "+wt);
|
||||
} else {
|
||||
tt = edt.typeSummary();
|
||||
}
|
||||
}
|
||||
if (!tt.equals(wt)) {
|
||||
boolean ok = !elementProfile && 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)
|
||||
throw new DefinitionException(smsg);
|
||||
else
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url+"#"+ed.getId(), smsg, IssueSeverity.ERROR));
|
||||
handleError(url, "The profile "+u.getValue()+" has type "+sd.getType()+" which is not consistent with the stated type "+wt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -738,6 +741,13 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
private void handleError(String url, String msg) {
|
||||
if (exception)
|
||||
throw new DefinitionException(msg);
|
||||
else
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ import org.hl7.fhir.utilities.TimeTracker;
|
|||
import org.hl7.fhir.utilities.TranslationServices;
|
||||
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
@ -338,6 +339,23 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
String patchUrl(String url, String resourceType);
|
||||
|
||||
/**
|
||||
* set this to false (default is true) if you don't want profiles loaded
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
IContextResourceLoader setLoadProfiles(boolean value);
|
||||
|
||||
/**
|
||||
* Called during the loading process - the loader can decide which resources to load.
|
||||
* At this point, only the .index.json is being read
|
||||
*
|
||||
* @param pi
|
||||
* @param pri
|
||||
* @return
|
||||
*/
|
||||
boolean wantLoad(NpmPackage pi, PackageResourceInformation pri);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -492,7 +492,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
types = Utilities.strings("StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem", "Measures" );
|
||||
}
|
||||
for (PackageResourceInformation pri : pi.listIndexedResources(types)) {
|
||||
if (!pri.getFilename().contains("ig-r4")) {
|
||||
if (!pri.getFilename().contains("ig-r4") && (loader == null || loader.wantLoad(pi, pri))) {
|
||||
try {
|
||||
registerResourceFromPackage(new PackageResourceLoader(pri, loader), new PackageInformation(pi));
|
||||
t++;
|
||||
|
|
|
@ -394,7 +394,7 @@ public class FmlParser extends ParserBase {
|
|||
if (rule.getChildrenByName("source").size() != 1 || !rule.getChildrenByName("source").get(0).hasChild("element"))
|
||||
throw lexer.error("Complex rules must have an explicit name");
|
||||
if (rule.getChildrenByName("source").get(0).hasChild("type"))
|
||||
rule.makeElement("name").setValue(rule.getChildrenByName("source").get(0).getNamedChildValue("element") + rule.getChildrenByName("source").get(0).getNamedChildValue("type"));
|
||||
rule.makeElement("name").setValue(rule.getChildrenByName("source").get(0).getNamedChildValue("element") + Utilities.capitalize(rule.getChildrenByName("source").get(0).getNamedChildValue("type")));
|
||||
else
|
||||
rule.makeElement("name").setValue(rule.getChildrenByName("source").get(0).getNamedChildValue("element"));
|
||||
}
|
||||
|
|
|
@ -1245,6 +1245,20 @@ public class StructureDefinition extends CanonicalResource {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public ElementDefinition getElementById(String id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
for (ElementDefinition ed : getElement()) {
|
||||
if (id.equals(ed.getId())) {
|
||||
return ed;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// end addition
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,7 @@ public class StructureMapRenderer extends TerminologyRenderer {
|
|||
if (n.equals(s) || n.equals("\"" + s + "\""))
|
||||
return true;
|
||||
if (source.get(0).hasType()) {
|
||||
s = source.get(0).getElement() + "-" + source.get(0).getType();
|
||||
s = source.get(0).getElement() + Utilities.capitalize(source.get(0).getType());
|
||||
return n.equals(s) || n.equals("\"" + s + "\"");
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hl7.fhir.r5.model.Bundle;
|
|||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
|
||||
|
||||
public class TestPackageLoader implements IContextResourceLoader {
|
||||
|
||||
|
@ -62,4 +63,14 @@ public class TestPackageLoader implements IContextResourceLoader {
|
|||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IContextResourceLoader setLoadProfiles(boolean value) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantLoad(NpmPackage pi, PackageResourceInformation pri) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1000,7 +1000,7 @@ public class StructureMapUtilities {
|
|||
if (rule.getSource().size() != 1 || !rule.getSourceFirstRep().hasElement() && exceptionsForChecks )
|
||||
throw lexer.error("Complex rules must have an explicit name");
|
||||
if (rule.getSourceFirstRep().hasType())
|
||||
rule.setName(rule.getSourceFirstRep().getElement() + "-" + rule.getSourceFirstRep().getType());
|
||||
rule.setName(rule.getSourceFirstRep().getElement() + Utilities.capitalize(rule.getSourceFirstRep().getType()));
|
||||
else
|
||||
rule.setName(rule.getSourceFirstRep().getElement());
|
||||
}
|
||||
|
|
|
@ -1543,10 +1543,13 @@ public class Utilities {
|
|||
ZipEntry zipEntry = zis.getNextEntry();
|
||||
while (zipEntry != null) {
|
||||
boolean isDirectory = false;
|
||||
if (zipEntry.getName().endsWith("/") || zipEntry.getName().endsWith("\\")) {
|
||||
|
||||
String n = makeOSSafe(zipEntry.getName());
|
||||
|
||||
if (n.endsWith(File.separator)) {
|
||||
isDirectory = true;
|
||||
}
|
||||
Path newPath = zipSlipProtect(zipEntry, target);
|
||||
Path newPath = zipSlipProtect(n, target);
|
||||
if (isDirectory) {
|
||||
Files.createDirectories(newPath);
|
||||
} else {
|
||||
|
@ -1563,19 +1566,23 @@ public class Utilities {
|
|||
}
|
||||
}
|
||||
|
||||
public static Path zipSlipProtect(ZipEntry zipEntry, Path targetDir)
|
||||
public static String makeOSSafe(String name) {
|
||||
return name.replace("\\", File.separator).replace("/", File.separator);
|
||||
}
|
||||
|
||||
public static Path zipSlipProtect(String zipName, Path targetDir)
|
||||
throws IOException {
|
||||
|
||||
// test zip slip vulnerability
|
||||
// Path targetDirResolved = targetDir.resolve("../../" + zipEntry.getName());
|
||||
|
||||
Path targetDirResolved = targetDir.resolve(zipEntry.getName());
|
||||
Path targetDirResolved = targetDir.resolve(zipName);
|
||||
|
||||
// make sure normalized file still has targetDir as its prefix
|
||||
// else throws exception
|
||||
Path normalizePath = targetDirResolved.normalize();
|
||||
if (!normalizePath.startsWith(targetDir)) {
|
||||
throw new IOException("Bad zip entry: " + zipEntry.getName());
|
||||
throw new IOException("Bad zip entry: " + zipName);
|
||||
}
|
||||
|
||||
return normalizePath;
|
||||
|
@ -1920,7 +1927,7 @@ public class Utilities {
|
|||
if (ignoreList == null || !ignoreList.contains(f.getAbsolutePath())) {
|
||||
if (f.isDirectory()) {
|
||||
addAllFiles(res, root, f, ignoreList);
|
||||
} else {
|
||||
} else if (!f.getName().equals(".DS_Store")) {
|
||||
res.add(getRelativePath(root, f.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2646,7 +2646,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (fetcher != null && !type.equals("uuid")) {
|
||||
boolean found;
|
||||
try {
|
||||
found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com")) || url.contains("acme.org")) || (url.startsWith("http://hl7.org/fhir/tools")) ||
|
||||
found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com")) || url.contains("acme.org")) /* || (url.startsWith("http://hl7.org/fhir/tools")) */ ||
|
||||
SpecialExtensions.isKnownExtension(url) || isXverUrl(url);
|
||||
if (!found) {
|
||||
found = fetcher.resolveURL(this, hostContext, path, url, type);
|
||||
|
|
|
@ -199,6 +199,11 @@ public class StructureMapValidator extends BaseValidator {
|
|||
return sd.getUrl().equals(other.sd.getUrl()) && ed.getPath().equals(other.ed.getPath()) && Utilities.stringsEqual(type, other.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return summary();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class VariableSet {
|
||||
|
@ -623,9 +628,15 @@ public class StructureMapValidator extends BaseValidator {
|
|||
} else {
|
||||
ok = false;
|
||||
}
|
||||
// check condition
|
||||
// check check
|
||||
}
|
||||
} else {
|
||||
String variable = source.getChildValue("variable");
|
||||
if (variable != null) {
|
||||
variables.add(variable, v.getMode()); // may overwrite
|
||||
|
||||
}
|
||||
// check condition
|
||||
// check check
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
|
@ -873,7 +884,7 @@ public class StructureMapValidator extends BaseValidator {
|
|||
// under some special conditions, we can infer what the type will be:
|
||||
// * there's a nominated default variable
|
||||
// * that variable has as single type
|
||||
// * there's a create with no param
|
||||
// * there's a create/copy with no param
|
||||
// * there's a single dependent rule with name = StructureMapUtilities.DEF_GROUP_NAME
|
||||
// * there's a default type group for the type of the source type
|
||||
// otherwise, we can't know the target type.
|
||||
|
@ -882,11 +893,25 @@ public class StructureMapValidator extends BaseValidator {
|
|||
VariableDefn v = variables.getVariable(ruleInfo.getDefVariable(), SOURCE);
|
||||
if (v != null && v.getEd() != null && (v.getEd().getType().size() == 1 || v.getType() != null)) {
|
||||
List<Element> dependents = rule.getChildrenByName("dependent");
|
||||
String type = v.getType() != null ? getTypeFromDefn(v.getEd(), v.getType()) : v.getEd().getTypeFirstRep().getWorkingCode();
|
||||
if (dependents.size() == 1 && StructureMapUtilities.DEF_GROUP_NAME.equals(dependents.get(0).getChildValue("name"))) {
|
||||
String type = v.getType() != null ? getTypeFromDefn(v.getEd(), v.getType()) : v.getEd().getTypeFirstRep().getWorkingCode();
|
||||
// now, we look for a default group.
|
||||
// todo: look in this source
|
||||
// now look through the inputs
|
||||
for (StructureMap map : imports) {
|
||||
for (StructureMapGroupComponent grp : map.getGroup()) {
|
||||
if (grp.getTypeMode() != StructureMapGroupTypeMode.NULL && grp.getInput().size() == 2) {
|
||||
String grpType = getTypeForGroupInput(map, grp, grp.getInput().get(0));
|
||||
if (sameTypes(type, grpType)) {
|
||||
String tgtType = getTypeForGroupInput(map, grp, grp.getInput().get(1));
|
||||
if (tgtType != null) {
|
||||
return tgtType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dependents.size() == 0) {
|
||||
for (StructureMap map : imports) {
|
||||
for (StructureMapGroupComponent grp : map.getGroup()) {
|
||||
if (grp.getTypeMode() == StructureMapGroupTypeMode.TYPEANDTYPES && grp.getInput().size() == 2) {
|
||||
|
@ -900,6 +925,7 @@ public class StructureMapValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -19,7 +19,7 @@
|
|||
|
||||
<properties>
|
||||
<hapi_fhir_version>6.2.1</hapi_fhir_version>
|
||||
<validator_test_case_version>1.2.21</validator_test_case_version>
|
||||
<validator_test_case_version>1.2.22-SNAPSHOT</validator_test_case_version>
|
||||
<junit_jupiter_version>5.7.1</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||
<maven_surefire_version>3.0.0-M5</maven_surefire_version>
|
||||
|
|
Loading…
Reference in New Issue