refactor profile handling in validator

This commit is contained in:
Grahame Grieve 2020-01-16 23:37:30 +11:00
parent 494b268d0b
commit 8482ba43c5
5 changed files with 674 additions and 582 deletions

View File

@ -60,7 +60,12 @@ public interface IResourceValidator {
} }
} }
public interface IValidationProfileUsageTracker {
void recordProfileUsage(StructureDefinition profile, Object appContext, Element element);
}
public interface IValidatorResourceFetcher { public interface IValidatorResourceFetcher {
Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException; Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException;
ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url); ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url);
boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException; boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException;
@ -113,7 +118,10 @@ public interface IResourceValidator {
IValidatorResourceFetcher getFetcher(); IValidatorResourceFetcher getFetcher();
IResourceValidator setFetcher(IValidatorResourceFetcher value); IResourceValidator setFetcher(IValidatorResourceFetcher value);
IValidationProfileUsageTracker getTracker();
IResourceValidator setTracker(IValidationProfileUsageTracker value);
boolean isNoBindingMsgSuppressed(); boolean isNoBindingMsgSuppressed();
IResourceValidator setNoBindingMsgSuppressed(boolean noBindingMsgSuppressed); IResourceValidator setNoBindingMsgSuppressed(boolean noBindingMsgSuppressed);
@ -133,6 +141,9 @@ public interface IResourceValidator {
public boolean isErrorForUnknownProfiles(); public boolean isErrorForUnknownProfiles();
public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles); public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles);
public boolean isShowMessagesFromReferences();
public void setShowMessagesFromReferences(boolean value);
public String getValidationLanguage(); public String getValidationLanguage();
public void setValidationLanguage(String value); public void setValidationLanguage(String value);
@ -155,34 +166,28 @@ public interface IResourceValidator {
* @throws IOException * @throws IOException
*/ */
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.elementmodel.Element element) throws FHIRException; void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.elementmodel.Element element) throws FHIRException;
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.elementmodel.Element element, ValidationProfileSet profiles) throws FHIRException;
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.elementmodel.Element element, String profile) throws FHIRException; void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.elementmodel.Element element, String profile) throws FHIRException;
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.elementmodel.Element element, StructureDefinition profile) throws FHIRException; void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.elementmodel.Element element, List<StructureDefinition> profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, ValidationProfileSet profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, String profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, String profile) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, StructureDefinition profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, List<StructureDefinition> profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.model.Resource resource) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.model.Resource resource) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.model.Resource resource, ValidationProfileSet profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.model.Resource resource, String profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.model.Resource resource, String profile) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.model.Resource resource, StructureDefinition profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r5.model.Resource resource, List<StructureDefinition> profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, ValidationProfileSet profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, String profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, String profile) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, StructureDefinition profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, List<StructureDefinition> profile) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, ValidationProfileSet profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, String profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, String profile) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, StructureDefinition profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, List<StructureDefinition> profile) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, ValidationProfileSet profiles) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, String profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, String profile) throws FHIRException;
org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, StructureDefinition profile) throws FHIRException; org.hl7.fhir.r5.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, List<StructureDefinition> profile) throws FHIRException;
} }

View File

@ -1,111 +0,0 @@
package org.hl7.fhir.r5.utils;
/*-
* #%L
* org.hl7.fhir.r5
* %%
* Copyright (C) 2014 - 2019 Health Level 7
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hl7.fhir.r5.model.StructureDefinition;
public class ValidationProfileSet {
public static class ProfileRegistration {
private String profile;
private boolean errorOnMissing;
public ProfileRegistration(String profile, boolean errorOnMissing) {
super();
this.profile = profile;
this.errorOnMissing = errorOnMissing;
}
public String getProfile() {
return profile;
}
public boolean isErrorOnMissing() {
return errorOnMissing;
}
}
private List<ProfileRegistration> canonical = new ArrayList<ProfileRegistration>();
private List<StructureDefinition> definitions = new ArrayList<StructureDefinition>();
public ValidationProfileSet(String profile, boolean isError) {
super();
canonical.add(new ProfileRegistration(profile, isError));
}
public ValidationProfileSet() {
super();
}
public ValidationProfileSet(StructureDefinition profile) {
super();
definitions.add(profile);
canonical.add(new ProfileRegistration(profile.getUrl(), true));
}
public ValidationProfileSet(List<String> profiles, boolean isError) {
super();
if (profiles != null)
for (String p : profiles)
canonical.add(new ProfileRegistration(p, isError));
}
public List<String> getCanonicalUrls() {
List<String> res = new ArrayList<String>();
for (ProfileRegistration c : canonical) {
res.add(c.getProfile());
}
return res;
}
public List<StructureDefinition> getDefinitions() {
return definitions;
}
public boolean empty() {
return canonical.isEmpty() && definitions.isEmpty();
}
public List<String> getCanonicalAll() {
Set<String> res = new HashSet<String>();
res.addAll(getCanonicalUrls());
for (StructureDefinition sd : definitions)
res.add(sd.getUrl());
return new ArrayList<String>(res);
}
public List<ProfileRegistration> getCanonical() {
return canonical;
}
public StructureDefinition fetch(String effectiveProfile) {
for (StructureDefinition sd : definitions)
if (effectiveProfile.equals(sd.getUrl()))
return sd;
return null;
}
}

View File

@ -146,7 +146,6 @@ import org.hl7.fhir.r5.utils.StructureMapUtilities;
import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices; import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices;
import org.hl7.fhir.r5.validation.ValidationEngine.ScanOutputItem; import org.hl7.fhir.r5.validation.ValidationEngine.ScanOutputItem;
import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.ValidationProfileSet;
import org.hl7.fhir.utilities.IniFile; import org.hl7.fhir.utilities.IniFile;
import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
@ -307,6 +306,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
private PrintWriter mapLog; private PrintWriter mapLog;
private boolean debug; private boolean debug;
private Set<String> loadedIgs = new HashSet<>(); private Set<String> loadedIgs = new HashSet<>();
private IValidatorResourceFetcher fetcher;
private class AsteriskFilter implements FilenameFilter { private class AsteriskFilter implements FilenameFilter {
String dir; String dir;
@ -946,9 +946,23 @@ public class ValidationEngine implements IValidatorResourceFetcher {
public OperationOutcome validate(FhirFormat format, InputStream stream, List<String> profiles) throws Exception { public OperationOutcome validate(FhirFormat format, InputStream stream, List<String> profiles) throws Exception {
List<ValidationMessage> messages = new ArrayList<ValidationMessage>(); List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
InstanceValidator validator = getValidator(); InstanceValidator validator = getValidator();
validator.validate(null, messages, stream, format, new ValidationProfileSet(profiles, true)); validator.validate(null, messages, stream, format, asSdList(profiles));
return messagesToOutcome(messages); return messagesToOutcome(messages);
} }
public List<StructureDefinition> asSdList(List<String> profiles) throws Error {
List<StructureDefinition> list = new ArrayList<>();
if (profiles != null) {
for (String p : profiles) {
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p);
if (sd == null) {
throw new Error("Unable to resolve profile "+p);
}
list.add(sd);
}
}
return list;
}
public OperationOutcome validate(String source, List<String> profiles) throws Exception { public OperationOutcome validate(String source, List<String> profiles) throws Exception {
List<String> l = new ArrayList<String>(); List<String> l = new ArrayList<String>();
@ -986,7 +1000,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
try { try {
System.out.println("Validate "+ref+" against "+ig.getUrl()); System.out.println("Validate "+ref+" against "+ig.getUrl());
messages.clear(); messages.clear();
validator.validate(null, messages, new ByteArrayInputStream(cnt.focus), cnt.cntType, new ValidationProfileSet(url, true)); validator.validate(null, messages, new ByteArrayInputStream(cnt.focus), cnt.cntType, url);
res.add(new ScanOutputItem(ref, ig, null, messagesToOutcome(messages))); res.add(new ScanOutputItem(ref, ig, null, messagesToOutcome(messages)));
} catch (Exception ex) { } catch (Exception ex) {
res.add(new ScanOutputItem(ref, ig, null, exceptionToOutcome(ex))); res.add(new ScanOutputItem(ref, ig, null, exceptionToOutcome(ex)));
@ -1000,7 +1014,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
try { try {
System.out.println("Validate "+ref+" against "+sd.getUrl()); System.out.println("Validate "+ref+" against "+sd.getUrl());
messages.clear(); messages.clear();
validator.validate(null, messages, new ByteArrayInputStream(cnt.focus), cnt.cntType, new ValidationProfileSet(sd.getUrl(), true)); validator.validate(null, messages, new ByteArrayInputStream(cnt.focus), cnt.cntType, asSdList(sd));
res.add(new ScanOutputItem(ref, ig, sd, messagesToOutcome(messages))); res.add(new ScanOutputItem(ref, ig, sd, messagesToOutcome(messages)));
} catch (Exception ex) { } catch (Exception ex) {
res.add(new ScanOutputItem(ref, ig, sd, exceptionToOutcome(ex))); res.add(new ScanOutputItem(ref, ig, sd, exceptionToOutcome(ex)));
@ -1014,6 +1028,12 @@ public class ValidationEngine implements IValidatorResourceFetcher {
return res; return res;
} }
private List<StructureDefinition> asSdList(StructureDefinition sd) {
List<StructureDefinition> res = new ArrayList<StructureDefinition>();
res.add(sd);
return res;
}
private Resource resolve(Reference reference) { private Resource resolve(Reference reference) {
return null; return null;
} }
@ -1122,7 +1142,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
validateSHEX(location, messages); validateSHEX(location, messages);
} }
InstanceValidator validator = getValidator(); InstanceValidator validator = getValidator();
validator.validate(null, messages, new ByteArrayInputStream(source), cntType, new ValidationProfileSet(profiles, true)); validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles));
return messagesToOutcome(messages); return messagesToOutcome(messages);
} }
@ -1140,7 +1160,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
validator.setResourceIdRule(resourceIdRule); validator.setResourceIdRule(resourceIdRule);
validator.setBestPracticeWarningLevel(bpWarnings); validator.setBestPracticeWarningLevel(bpWarnings);
validator.setCheckDisplay(displayOption); validator.setCheckDisplay(displayOption);
validator.validate(null, messages, new ByteArrayInputStream(source), cntType, new ValidationProfileSet(profiles, true)); validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles));
return messagesToOutcome(messages); return messagesToOutcome(messages);
} }
@ -1597,13 +1617,15 @@ public class ValidationEngine implements IValidatorResourceFetcher {
@Override @Override
public Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException { public Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
return null; return fetcher != null ? fetcher.fetch(appContext, url) : null;
} }
@Override @Override
public ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url) { public ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url) {
if (!url.startsWith("http://hl7.org/fhir")) { if (!url.startsWith("http://hl7.org/fhir")) {
return ReferenceValidationPolicy.IGNORE; return ReferenceValidationPolicy.IGNORE;
} else if (fetcher != null) {
return fetcher.validationPolicy(appContext, path, url);
} else { } else {
return ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE; return ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE;
} }
@ -1620,6 +1642,9 @@ public class ValidationEngine implements IValidatorResourceFetcher {
"http://hl7.org/fhir/workflow", "http://hl7.org/fhir/ConsentPolicy/opt-out", "http://hl7.org/fhir/ConsentPolicy/opt-in")) { "http://hl7.org/fhir/workflow", "http://hl7.org/fhir/ConsentPolicy/opt-out", "http://hl7.org/fhir/ConsentPolicy/opt-in")) {
return true; return true;
} }
if (fetcher != null) {
return fetcher.resolveURL(appContext, path, url);
};
return false; return false;
} }
@ -1711,6 +1736,14 @@ public class ValidationEngine implements IValidatorResourceFetcher {
context.getExpansionParameters().addParameter("system-version", "http://snomed.info/sct|"+sct); context.getExpansionParameters().addParameter("system-version", "http://snomed.info/sct|"+sct);
} }
public IValidatorResourceFetcher getFetcher() {
return fetcher;
}
public void setFetcher(IValidatorResourceFetcher fetcher) {
this.fetcher = fetcher;
}
} }

View File

@ -119,6 +119,7 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
throw new Exception("unknown version "+v); throw new Exception("unknown version "+v);
} }
vCurr = ve.get(v); vCurr = ve.get(v);
vCurr.setFetcher(this);
TestingUtilities.fcontext = vCurr.getContext(); TestingUtilities.fcontext = vCurr.getContext();
if (content.has("use-test") && !content.get("use-test").getAsBoolean()) if (content.has("use-test") && !content.get("use-test").getAsBoolean())
@ -185,11 +186,12 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
System.out.println("Name: " + name+" - profile : "+profile.get("source").getAsString()); System.out.println("Name: " + name+" - profile : "+profile.get("source").getAsString());
v = content.has("version") ? content.get("version").getAsString() : Constants.VERSION; v = content.has("version") ? content.get("version").getAsString() : Constants.VERSION;
StructureDefinition sd = loadProfile(filename, contents, v, messages); StructureDefinition sd = loadProfile(filename, contents, v, messages);
val.getContext().cacheResource(sd);
List<ValidationMessage> errorsProfile = new ArrayList<ValidationMessage>(); List<ValidationMessage> errorsProfile = new ArrayList<ValidationMessage>();
if (name.endsWith(".json")) if (name.endsWith(".json"))
val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.JSON, sd); val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.JSON, asSdList(sd));
else else
val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.XML, sd); val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.XML, asSdList(sd));
checkOutcomes(errorsProfile, profile); checkOutcomes(errorsProfile, profile);
} }
if (content.has("logical")) { if (content.has("logical")) {
@ -218,6 +220,11 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
} }
} }
private List<StructureDefinition> asSdList(StructureDefinition sd) {
List<StructureDefinition> res = new ArrayList<StructureDefinition>();
res.add(sd);
return res;
}
public StructureDefinition loadProfile(String filename, String contents, String v, List<ValidationMessage> messages) throws IOException, FHIRFormatError, FileNotFoundException, FHIRException, DefinitionException { public StructureDefinition loadProfile(String filename, String contents, String v, List<ValidationMessage> messages) throws IOException, FHIRFormatError, FileNotFoundException, FHIRException, DefinitionException {
StructureDefinition sd = (StructureDefinition) loadResource(filename, contents, v); StructureDefinition sd = (StructureDefinition) loadResource(filename, contents, v);
@ -355,15 +362,23 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
@Override @Override
public Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, IOException, FHIRException { public Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, IOException, FHIRException {
if (url.equals("Patient/test")) Element res = null;
return new ObjectConverter(TestingUtilities.context()).convert(new Patient()); if (url.equals("Patient/test")) {
if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase()+".json")) { res = new ObjectConverter(TestingUtilities.context()).convert(new Patient());
return Manager.makeParser(TestingUtilities.context(), FhirFormat.JSON).parse(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase()+".json")); } else if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase()+".json")) {
res = Manager.makeParser(TestingUtilities.context(), FhirFormat.JSON).parse(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase()+".json"));
} else if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase()+".xml")) {
res = Manager.makeParser(TestingUtilities.context(), FhirFormat.XML).parse(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase()+".xml"));
} }
if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase()+".xml")) { if (res == null && url.contains("/")) {
return Manager.makeParser(TestingUtilities.context(), FhirFormat.JSON).parse(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase()+".xml")); String tail = url.substring(url.indexOf("/")+1);
if (TestingUtilities.findTestResource("validator", tail.replace("/", "-").toLowerCase()+".json")) {
res = Manager.makeParser(TestingUtilities.context(), FhirFormat.JSON).parse(TestingUtilities.loadTestResourceStream("validator", tail.replace("/", "-").toLowerCase()+".json"));
} else if (TestingUtilities.findTestResource("validator", tail.replace("/", "-").toLowerCase()+".xml")) {
res = Manager.makeParser(TestingUtilities.context(), FhirFormat.XML).parse(TestingUtilities.loadTestResourceStream("validator", tail.replace("/", "-").toLowerCase()+".xml"));
}
} }
return null; return res;
} }
@Override @Override