Merge pull request #544 from hapifhir/gg-202106-validator-paths
Gg 202106 validator paths
This commit is contained in:
commit
e022acb569
|
@ -53,6 +53,7 @@ import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
|||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ILoggingService.LogCategory;
|
||||
import org.hl7.fhir.r5.context.TerminologyCache.CacheToken;
|
||||
import org.hl7.fhir.r5.model.BooleanType;
|
||||
|
@ -159,7 +160,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
|
||||
private Object lock = new Object(); // used as a lock for the data that follows
|
||||
protected String version;
|
||||
protected String version; // although the internal resources are all R5, the version of FHIR they describe may not be
|
||||
private String cacheId;
|
||||
private boolean isTxCaching;
|
||||
private Set<String> cached = new HashSet<>();
|
||||
|
@ -266,9 +267,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
}
|
||||
|
||||
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies) {
|
||||
// nothing yet
|
||||
}
|
||||
|
||||
public void cacheResource(Resource r) throws FHIRException {
|
||||
cacheResourceFromPackage(r, null);
|
||||
|
@ -1317,6 +1315,65 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
}
|
||||
|
||||
public PackageVersion getPackageForUrl(String uri) {
|
||||
if (uri == null) {
|
||||
return null;
|
||||
}
|
||||
uri = ProfileUtilities.sdNs(uri, getOverrideVersionNs());
|
||||
|
||||
synchronized (lock) {
|
||||
|
||||
String version = null;
|
||||
if (uri.contains("|")) {
|
||||
version = uri.substring(uri.lastIndexOf("|")+1);
|
||||
uri = uri.substring(0, uri.lastIndexOf("|"));
|
||||
}
|
||||
if (uri.contains("#")) {
|
||||
uri = uri.substring(0, uri.indexOf("#"));
|
||||
}
|
||||
if (structures.has(uri)) {
|
||||
return structures.getPackageInfo(uri, version);
|
||||
}
|
||||
if (guides.has(uri)) {
|
||||
return guides.getPackageInfo(uri, version);
|
||||
}
|
||||
if (capstmts.has(uri)) {
|
||||
return capstmts.getPackageInfo(uri, version);
|
||||
}
|
||||
if (measures.has(uri)) {
|
||||
return measures.getPackageInfo(uri, version);
|
||||
}
|
||||
if (libraries.has(uri)) {
|
||||
return libraries.getPackageInfo(uri, version);
|
||||
}
|
||||
if (valueSets.has(uri)) {
|
||||
return valueSets.getPackageInfo(uri, version);
|
||||
}
|
||||
if (codeSystems.has(uri)) {
|
||||
return codeSystems.getPackageInfo(uri, version);
|
||||
}
|
||||
if (operations.has(uri)) {
|
||||
return operations.getPackageInfo(uri, version);
|
||||
}
|
||||
if (searchParameters.has(uri)) {
|
||||
return searchParameters.getPackageInfo(uri, version);
|
||||
}
|
||||
if (plans.has(uri)) {
|
||||
return plans.getPackageInfo(uri, version);
|
||||
}
|
||||
if (maps.has(uri)) {
|
||||
return maps.getPackageInfo(uri, version);
|
||||
}
|
||||
if (transforms.has(uri)) {
|
||||
return transforms.getPackageInfo(uri, version);
|
||||
}
|
||||
if (questionnaires.has(uri)) {
|
||||
return questionnaires.getPackageInfo(uri, version);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Resource> T fetchResourceWithException(String cls, String uri, CanonicalResource source) throws FHIRException {
|
||||
if (uri == null) {
|
||||
|
@ -1840,6 +1897,10 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
|
||||
public String getLinkForUrl(String corePath, String url) {
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (codeSystems.has(url)) {
|
||||
return codeSystems.get(url).getUserString("path");
|
||||
}
|
||||
|
|
|
@ -292,6 +292,20 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
return map.containsKey(url) ? map.get(url).getResource() : null;
|
||||
}
|
||||
|
||||
public PackageVersion getPackageInfo(String system, String version) {
|
||||
if (version == null) {
|
||||
return map.containsKey(system) ? map.get(system).getPackageInfo() : null;
|
||||
} else {
|
||||
if (map.containsKey(system+"|"+version))
|
||||
return map.get(system+"|"+version).getPackageInfo();
|
||||
String mm = VersionUtilities.getMajMin(version);
|
||||
if (mm != null && map.containsKey(system+"|"+mm))
|
||||
return map.get(system+"|"+mm).getPackageInfo();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean has(String url) {
|
||||
return map.containsKey(url);
|
||||
}
|
||||
|
|
|
@ -170,6 +170,27 @@ public interface IWorkerContext {
|
|||
}
|
||||
}
|
||||
|
||||
public class PackageDetails extends PackageVersion {
|
||||
private String name;
|
||||
private String canonical;
|
||||
private String web;
|
||||
public PackageDetails(String id, String version, String name, String canonical, String web) {
|
||||
super(id, version);
|
||||
this.name = name;
|
||||
this.canonical = canonical;
|
||||
this.web = web;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public String getCanonical() {
|
||||
return canonical;
|
||||
}
|
||||
public String getWeb() {
|
||||
return web;
|
||||
}
|
||||
|
||||
}
|
||||
public interface ICanonicalResourceLocator {
|
||||
void findResource(Object caller, String url); // if it can be found, put it in the context
|
||||
}
|
||||
|
@ -387,7 +408,7 @@ public interface IWorkerContext {
|
|||
*
|
||||
* @param packageInfo
|
||||
*/
|
||||
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies);
|
||||
public void cachePackage(PackageDetails packageDetails, List<PackageVersion> dependencies);
|
||||
|
||||
// -- profile services ---------------------------------------------------------
|
||||
|
||||
|
@ -780,9 +801,13 @@ public interface IWorkerContext {
|
|||
int loadFromPackageAndDependencies(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm) throws FileNotFoundException, IOException, FHIRException;
|
||||
|
||||
public boolean hasPackage(String id, String ver);
|
||||
public boolean hasPackage(PackageVersion pack);
|
||||
public PackageDetails getPackage(PackageVersion pack);
|
||||
|
||||
public int getClientRetryCount();
|
||||
public IWorkerContext setClientRetryCount(int value);
|
||||
|
||||
public TimeTracker clock();
|
||||
|
||||
public PackageVersion getPackageForUrl(String url);
|
||||
}
|
|
@ -54,6 +54,7 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
|||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ILoggingService.LogCategory;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext.PackageResourceLoader;
|
||||
import org.hl7.fhir.r5.formats.IParser;
|
||||
|
@ -810,15 +811,6 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
this.progress = progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPackage(String id, String ver) {
|
||||
return loadedPackages.contains(id+"#"+ver);
|
||||
}
|
||||
|
||||
public boolean hasPackage(String idAndver) {
|
||||
return loadedPackages.contains(idAndver);
|
||||
}
|
||||
|
||||
public void setClock(TimeTracker tt) {
|
||||
clock = tt;
|
||||
}
|
||||
|
@ -837,5 +829,34 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
}
|
||||
return xverManager;
|
||||
}
|
||||
|
||||
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies) {
|
||||
// nothing yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPackage(String id, String ver) {
|
||||
return loadedPackages.contains(id+"#"+ver);
|
||||
}
|
||||
|
||||
public boolean hasPackage(String idAndver) {
|
||||
return loadedPackages.contains(idAndver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cachePackage(PackageDetails packageDetails, List<PackageVersion> dependencies) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPackage(PackageVersion pack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageDetails getPackage(PackageVersion pack) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
|||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.utilities.ElementDecoration;
|
||||
import org.hl7.fhir.utilities.ElementDecoration.DecorationType;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
|
@ -102,6 +103,8 @@ public class Element extends Base {
|
|||
private String explicitType; // for xsi:type attribute
|
||||
private Element parentForValidator;
|
||||
private boolean hasParentForValidator;
|
||||
private String path;
|
||||
private List<ValidationMessage> messages;
|
||||
|
||||
public Element(String name) {
|
||||
super();
|
||||
|
@ -706,6 +709,13 @@ public class Element extends Base {
|
|||
return property.isList();
|
||||
}
|
||||
|
||||
public boolean isBaseList() {
|
||||
if (elementProperty != null)
|
||||
return elementProperty.isBaseList();
|
||||
else
|
||||
return property.isBaseList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTypesForProperty(int hash, String name) throws FHIRException {
|
||||
Property p = property.getChildSimpleName(this.name, name);
|
||||
|
@ -938,6 +948,29 @@ public class Element extends Base {
|
|||
property = null;
|
||||
elementProperty = null;
|
||||
xhtml = null;
|
||||
path = null;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public void addMessage(ValidationMessage vm) {
|
||||
if (messages == null) {
|
||||
messages = new ArrayList<>();
|
||||
}
|
||||
messages.add(vm);
|
||||
}
|
||||
|
||||
public boolean hasMessages() {
|
||||
return messages != null && !messages.isEmpty();
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
}
|
|
@ -98,6 +98,7 @@ public class JsonParser extends ParserBase {
|
|||
return null;
|
||||
|
||||
Element result = new Element(type, new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities));
|
||||
result.setPath(type);
|
||||
checkObject(obj, path);
|
||||
result.setType(type);
|
||||
parseChildren(path, obj, result, true);
|
||||
|
@ -123,7 +124,7 @@ public class JsonParser extends ParserBase {
|
|||
return parse(obj);
|
||||
} else {
|
||||
JsonObject obj = JsonTrackingParser.parse(source, null); // (JsonObject) new com.google.gson.JsonParser().parse(source);
|
||||
// assert (map.containsKey(obj));
|
||||
// assert (map.containsKey(obj));
|
||||
return parse(obj);
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +151,7 @@ public class JsonParser extends ParserBase {
|
|||
checkObject(object, path);
|
||||
result.markLocation(line(object), col(object));
|
||||
result.setType(name);
|
||||
result.setPath(result.fhirType());
|
||||
parseChildren(path, object, result, true);
|
||||
result.numberChildren();
|
||||
return result;
|
||||
|
@ -215,6 +217,7 @@ public class JsonParser extends ParserBase {
|
|||
private void parseChildComplex(String path, JsonObject object, Element element, Set<String> processed, Property property, String name) throws FHIRException {
|
||||
processed.add(name);
|
||||
String npath = path+"."+property.getName();
|
||||
String fpath = element.getPath()+"."+property.getName();
|
||||
JsonElement e = object.get(name);
|
||||
if (property.isList() && (e instanceof JsonArray)) {
|
||||
JsonArray arr = (JsonArray) e;
|
||||
|
@ -223,14 +226,14 @@ public class JsonParser extends ParserBase {
|
|||
}
|
||||
int c = 0;
|
||||
for (JsonElement am : arr) {
|
||||
parseChildComplexInstance(npath+"["+c+"]", object, element, property, name, am);
|
||||
parseChildComplexInstance(npath+"["+c+"]", fpath+"["+c+"]", object, element, property, name, am);
|
||||
c++;
|
||||
}
|
||||
} else {
|
||||
if (property.isList()) {
|
||||
logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describeType(e), name, path), IssueSeverity.ERROR);
|
||||
}
|
||||
parseChildComplexInstance(npath, object, element, property, name, e);
|
||||
parseChildComplexInstance(npath, fpath, object, element, property, name, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,10 +249,11 @@ public class JsonParser extends ParserBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void parseChildComplexInstance(String npath, JsonObject object, Element element, Property property, String name, JsonElement e) throws FHIRException {
|
||||
private void parseChildComplexInstance(String npath, String fpath, JsonObject object, Element element, Property property, String name, JsonElement e) throws FHIRException {
|
||||
if (e instanceof JsonObject) {
|
||||
JsonObject child = (JsonObject) e;
|
||||
Element n = new Element(name, property).markLocation(line(child), col(child));
|
||||
n.setPath(fpath);
|
||||
checkObject(child, npath);
|
||||
element.getChildren().add(n);
|
||||
if (property.isResource())
|
||||
|
@ -275,6 +279,7 @@ public class JsonParser extends ParserBase {
|
|||
|
||||
private void parseChildPrimitive(JsonObject object, Element element, Set<String> processed, Property property, String path, String name) throws FHIRException {
|
||||
String npath = path+"."+property.getName();
|
||||
String fpath = element.getPath()+"."+property.getName();
|
||||
processed.add(name);
|
||||
processed.add("_"+name);
|
||||
JsonElement main = object.has(name) ? object.get(name) : null;
|
||||
|
@ -296,11 +301,11 @@ public class JsonParser extends ParserBase {
|
|||
for (int i = 0; i < Math.max(arrC(arr1), arrC(arr2)); i++) {
|
||||
JsonElement m = arrI(arr1, i);
|
||||
JsonElement f = arrI(arr2, i);
|
||||
parseChildPrimitiveInstance(element, property, name, npath, m, f);
|
||||
parseChildPrimitiveInstance(element, property, name, npath, fpath, m, f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parseChildPrimitiveInstance(element, property, name, npath, main, fork);
|
||||
parseChildPrimitiveInstance(element, property, name, npath, fpath, main, fork);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,8 +318,7 @@ public class JsonParser extends ParserBase {
|
|||
return arr == null ? 0 : arr.size();
|
||||
}
|
||||
|
||||
private void parseChildPrimitiveInstance(Element element, Property property, String name, String npath,
|
||||
JsonElement main, JsonElement fork) throws FHIRException {
|
||||
private void parseChildPrimitiveInstance(Element element, Property property, String name, String npath, String fpath, JsonElement main, JsonElement fork) throws FHIRException {
|
||||
if (main != null && !(main instanceof JsonPrimitive))
|
||||
logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(
|
||||
I18nConstants.THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_, describe(main), name, npath), IssueSeverity.ERROR);
|
||||
|
@ -322,6 +326,7 @@ public class JsonParser extends ParserBase {
|
|||
logError(line(fork), col(fork), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(fork), name, npath), IssueSeverity.ERROR);
|
||||
else {
|
||||
Element n = new Element(name, property).markLocation(line(main != null ? main : fork), col(main != null ? main : fork));
|
||||
n.setPath(fpath);
|
||||
element.getChildren().add(n);
|
||||
if (main != null) {
|
||||
JsonPrimitive p = (JsonPrimitive) main;
|
||||
|
|
|
@ -232,6 +232,10 @@ public class Property {
|
|||
return !"1".equals(definition.getMax());
|
||||
}
|
||||
|
||||
public boolean isBaseList() {
|
||||
return !"1".equals(definition.getBase().getMax());
|
||||
}
|
||||
|
||||
public String getScopedPropertyName() {
|
||||
return definition.getBase().getPath();
|
||||
}
|
||||
|
|
|
@ -203,6 +203,7 @@ public class XmlParser extends ParserBase {
|
|||
return null;
|
||||
|
||||
Element result = new Element(element.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
||||
result.setPath(element.getLocalName());
|
||||
checkElement(element, path, result.getProperty());
|
||||
result.markLocation(line(element), col(element));
|
||||
result.setType(element.getLocalName());
|
||||
|
@ -262,6 +263,7 @@ public class XmlParser extends ParserBase {
|
|||
public Element parse(org.w3c.dom.Element base, String type) throws Exception {
|
||||
StructureDefinition sd = getDefinition(0, 0, FormatUtilities.FHIR_NS, type);
|
||||
Element result = new Element(base.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
||||
result.setPath(base.getLocalName());
|
||||
String path = "/"+pathPrefix(base.getNamespaceURI())+base.getLocalName();
|
||||
checkElement(base, path, result.getProperty());
|
||||
result.setType(base.getLocalName());
|
||||
|
@ -283,13 +285,18 @@ public class XmlParser extends ParserBase {
|
|||
if (property != null) {
|
||||
if ("ED.data[x]".equals(property.getDefinition().getId()) || (property.getDefinition()!=null && property.getDefinition().getBase()!=null && "ED.data[x]".equals(property.getDefinition().getBase().getPath()))) {
|
||||
if ("B64".equals(node.getAttribute("representation"))) {
|
||||
element.getChildren().add(new Element("dataBase64Binary", property, "base64Binary", text).markLocation(line, col));
|
||||
Element n = new Element("dataBase64Binary", property, "base64Binary", text).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
} else {
|
||||
element.getChildren().add(new Element("dataString", property, "string", text).markLocation(line, col));
|
||||
Element n = new Element("dataString", property, "string", text).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
}
|
||||
} else {
|
||||
element.getChildren().add(
|
||||
new Element(property.getName(), property, property.getType(), text).markLocation(line, col));
|
||||
Element n = new Element(property.getName(), property, property.getType(), text).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -325,8 +332,11 @@ public class XmlParser extends ParserBase {
|
|||
av = convertForDateFormatFromExternal(ToolingExtensions.readStringExtension(property.getDefinition(), "http://www.healthintersections.com.au/fhir/StructureDefinition/elementdefinition-dateformat"), av);
|
||||
if (property.getName().equals("value") && element.isPrimitive())
|
||||
element.setValue(av);
|
||||
else
|
||||
element.getChildren().add(new Element(property.getName(), property, property.getType(), av).markLocation(line, col));
|
||||
else {
|
||||
Element n = new Element(property.getName(), property, property.getType(), av).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
}
|
||||
} else {
|
||||
boolean ok = false;
|
||||
if (FormatUtilities.FHIR_NS.equals(node.getNamespaceURI())) {
|
||||
|
@ -342,21 +352,36 @@ public class XmlParser extends ParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
String lastName = null;
|
||||
int repeatCount = 0;
|
||||
Node child = node.getFirstChild();
|
||||
while (child != null) {
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Property property = getElementProp(properties, child.getLocalName(), child.getNamespaceURI());
|
||||
if (property != null) {
|
||||
if (property.getName().equals(lastName)) {
|
||||
repeatCount++;
|
||||
} else {
|
||||
lastName = property.getName();
|
||||
repeatCount = 0;
|
||||
}
|
||||
if (!property.isChoice() && "xhtml".equals(property.getType())) {
|
||||
XhtmlNode xhtml;
|
||||
if (property.getDefinition().hasRepresentation(PropertyRepresentation.CDATEXT))
|
||||
xhtml = new CDANarrativeFormat().convert((org.w3c.dom.Element) child);
|
||||
else
|
||||
xhtml = new XhtmlParser().setValidatorMode(true).parseHtmlNode((org.w3c.dom.Element) child);
|
||||
element.getChildren().add(new Element(property.getName(), property, "xhtml", new XhtmlComposer(XhtmlComposer.XML, false).compose(xhtml)).setXhtml(xhtml).markLocation(line(child), col(child)));
|
||||
Element n = new Element(property.getName(), property, "xhtml", new XhtmlComposer(XhtmlComposer.XML, false).compose(xhtml)).setXhtml(xhtml).markLocation(line(child), col(child));
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
} else {
|
||||
String npath = path+"/"+pathPrefix(child.getNamespaceURI())+child.getLocalName();
|
||||
Element n = new Element(child.getLocalName(), property).markLocation(line(child), col(child));
|
||||
if (property.isList()) {
|
||||
n.setPath(element.getPath()+"."+property.getName()+"["+repeatCount+"]");
|
||||
} else {
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
}
|
||||
checkElement((org.w3c.dom.Element) child, npath, n.getProperty());
|
||||
boolean ok = true;
|
||||
if (property.isChoice()) {
|
||||
|
|
|
@ -132,7 +132,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
li.tx(opt.getValue().primitiveValue());
|
||||
} else if (opt.getValue() instanceof Coding) {
|
||||
Coding c = (Coding) opt.getValue();
|
||||
String link = context.getWorker().getLinkForUrl(context.getSpecificationLink(), c.getSystem());
|
||||
String link = c.hasSystem() ? context.getWorker().getLinkForUrl(context.getSpecificationLink(), c.getSystem()) : null;
|
||||
if (link == null) {
|
||||
li.tx(c.getSystem()+"#"+c.getCode());
|
||||
} else {
|
||||
|
|
|
@ -583,6 +583,7 @@ 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_BASE = "VALIDATION_VAL_PROFILE_SIGNPOST_BASE";
|
||||
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";
|
||||
|
|
|
@ -790,8 +790,9 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
|
|||
return signpost;
|
||||
}
|
||||
|
||||
public void setSignpost(boolean signpost) {
|
||||
public ValidationMessage setSignpost(boolean signpost) {
|
||||
this.signpost = signpost;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -524,8 +524,9 @@ TYPE_CHECKS_PATTERN_CC_US = The pattern [system {0}, code {1}, display ''{2}'' a
|
|||
TYPE_CHECKS_FIXED_CC = The pattern [system {0}, code {1}, and display ''{2}''] defined in the profile {3} not found. Issues: {4}
|
||||
TYPE_CHECKS_FIXED_CC_US = The pattern [system {0}, code {1}, display ''{2}'' and userSelected {5}] defined in the profile {3} not found. Issues: {4}
|
||||
VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN = Global Profile reference ''{0}'' from IG {1} could not be resolved, so has not been checked
|
||||
VALIDATION_VAL_PROFILE_SIGNPOST_BASE = Validate resource against profile
|
||||
VALIDATION_VAL_PROFILE_SIGNPOST = Validate resource against profile {0}
|
||||
VALIDATION_VAL_PROFILE_SIGNPOST_META = Validate resource against profile {0} - listed in meta
|
||||
VALIDATION_VAL_PROFILE_SIGNPOST_META = Validate resource against profile {0} (per meta)
|
||||
VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM = Validate resource against profile {0} - provided as bundle param
|
||||
VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = Validate resource against profile {0} - a global profile in {1}
|
||||
ERROR_GENERATING_SNAPSHOT = Error generating Snapshot: {0} (this usually arises from a problem in the differential)
|
||||
|
@ -618,7 +619,7 @@ SD_NESTED_MUST_SUPPORT_SNAPSHOT = The element {0} has types/profiles/targets tha
|
|||
Unable_to_connect_to_terminology_server = Unable to connect to terminology server. Error = {0}
|
||||
SD_ED_TYPE_PROFILE_UNKNOWN = Unable to resolve profile {0}
|
||||
SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type it applies to
|
||||
SD_ED_TYPE_PROFILE_WRONG = Extension {0} is for type {1}, but the {3} element has type {2}
|
||||
SD_ED_TYPE_PROFILE_WRONG = Profile {0} is for type {1}, but the {3} element has type {2}
|
||||
SD_ED_TYPE_PROFILE_WRONG_TARGET = Profile {0} is for type {1}, which is not a {4} (which is required because the {3} element has type {2})
|
||||
SD_ED_TYPE_NO_TARGET_PROFILE = Type {0} does not allow for target Profiles
|
||||
TERMINOLOGY_TX_NOSVC_BOUND_REQ = Could not confirm that the codes provided are from the required value set {0} because there is no terminology service
|
||||
|
|
|
@ -618,7 +618,7 @@ SD_NESTED_MUST_SUPPORT_SNAPSHOT = Het element {0} heeft typen/profielen/targets
|
|||
Unable_to_connect_to_terminology_server = Kan niet verbinden met terminologieserver. Fout = {0}
|
||||
SD_ED_TYPE_PROFILE_UNKNOWN = Kan profiel {0} niet vinden
|
||||
SD_ED_TYPE_PROFILE_NOTYPE = Profiel {0} gevonden, maar kan niet bepalen op welke type deze van toepassing is
|
||||
SD_ED_TYPE_PROFILE_WRONG = Extensie {0} is voor type {1}, met het {3} element heeft type {2}
|
||||
SD_ED_TYPE_PROFILE_WRONG = Profiel {0} is voor type {1}, met het {3} element heeft type {2}
|
||||
SD_ED_TYPE_PROFILE_WRONG_TARGET = Profiel {0} is voor type {1}, wat geen {4} is (welke wordt vereist om het {3} element type {2} heeft)
|
||||
SD_ED_TYPE_NO_TARGET_PROFILE = Type {0} laat geen target Profielen toe
|
||||
TERMINOLOGY_TX_NOSVC_BOUND_REQ = Kan niet bevestigen dat de gevonden codes bestaan in de verplichte waardelijst {0} omdat er geen terminologieservice is
|
||||
|
|
|
@ -284,12 +284,9 @@ public class BaseValidator {
|
|||
return thePass;
|
||||
}
|
||||
|
||||
protected boolean signpost(List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) {
|
||||
if (!thePass) {
|
||||
protected ValidationMessage signpost(List<ValidationMessage> errors, IssueType type, int line, int col, String path, String theMessage, Object... theMessageArguments) {
|
||||
String message = context.formatMessage(theMessage, theMessageArguments);
|
||||
addValidationMessage(errors, type, line, col, path, message, IssueSeverity.INFORMATION, theMessage).setSignpost(true);
|
||||
}
|
||||
return thePass;
|
||||
return addValidationMessage(errors, type, line, col, path, message, IssueSeverity.INFORMATION, theMessage).setSignpost(true);
|
||||
}
|
||||
|
||||
protected boolean txHint(List<ValidationMessage> errors, String txLink, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) {
|
||||
|
|
|
@ -3270,8 +3270,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
rr.setResource(nstack.getElement());
|
||||
rr.setFocus(nstack.getElement());
|
||||
rr.setExternal(false);
|
||||
rr.setStack(nstack.push(nstack.getElement(), -1, nstack.getElement().getProperty().getDefinition(), nstack.getElement().getProperty().getDefinition()));
|
||||
rr.getStack().qualifyPath(".ofType("+nstack.getElement().fhirType()+")");
|
||||
rr.setStack(nstack);
|
||||
// rr.getStack().qualifyPath(".ofType("+nstack.getElement().fhirType()+")");
|
||||
System.out.println("-->"+nstack.getLiteralPath());
|
||||
return rr;
|
||||
}
|
||||
if (nstack.getElement().getSpecial() == SpecialElement.CONTAINED) {
|
||||
|
@ -3951,7 +3952,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
// checkSpecials = we're only going to run these tests if we are actually validating this content (as opposed to we looked it up)
|
||||
private void start(ValidatorHostContext hostContext, List<ValidationMessage> errors, Element resource, Element element, StructureDefinition defn, NodeStack stack) throws FHIRException {
|
||||
checkLang(resource, stack);
|
||||
signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST, defn.getUrl());
|
||||
if (crumbTrails) {
|
||||
element.addMessage(signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST, defn.getUrl()));
|
||||
}
|
||||
|
||||
if (BUNDLE.equals(element.fhirType())) {
|
||||
resolveBundleReferences(element, new ArrayList<Element>());
|
||||
|
@ -3996,7 +3999,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
if (sd != null) {
|
||||
signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_META, sd.getUrl());
|
||||
if (crumbTrails) {
|
||||
element.addMessage(signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_META, sd.getUrl()));
|
||||
}
|
||||
stack.resetIds();
|
||||
startInner(hostContext, errors, resource, element, sd, stack, false);
|
||||
}
|
||||
|
@ -4011,7 +4016,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (rt.equals(gl.getType())) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, gl.getProfile());
|
||||
if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), sd != null, I18nConstants.VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN, gl.getProfile())) {
|
||||
signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL, sd.getUrl(), ig.getUrl());
|
||||
if (crumbTrails) {
|
||||
element.addMessage(signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL, sd.getUrl(), ig.getUrl()));
|
||||
}
|
||||
stack.resetIds();
|
||||
startInner(hostContext, errors, resource, element, sd, stack, false);
|
||||
}
|
||||
|
@ -4517,13 +4524,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
type = null;
|
||||
}
|
||||
}
|
||||
NodeStack localStack = stack.push(ei.getElement(), ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType()));
|
||||
NodeStack localStack = stack.push(ei.getElement(), "*".equals(ei.getDefinition().getBase().getMax()) && ei.count == -1 ? 0 : ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType()));
|
||||
// if (debug) {
|
||||
// System.out.println(" check " + localStack.getLiteralPath()+" against "+ei.getDefinition().getId()+" in profile "+profile.getUrl());
|
||||
// }
|
||||
String localStackLiterapPath = localStack.getLiteralPath();
|
||||
String localStackLiteralPath = localStack.getLiteralPath();
|
||||
String eiPath = ei.getPath();
|
||||
assert (eiPath.equals(localStackLiterapPath)) : "ei.path: " + ei.getPath() + " - localStack.getLiteralPath: " + localStackLiterapPath;
|
||||
if (!eiPath.equals(localStackLiteralPath)) {
|
||||
assert (eiPath.equals(localStackLiteralPath)) : "ei.path: " + ei.getPath() + " - localStack.getLiteralPath: " + localStackLiteralPath;
|
||||
}
|
||||
boolean thisIsCodeableConcept = false;
|
||||
String thisExtension = null;
|
||||
boolean checkDisplay = true;
|
||||
|
|
|
@ -112,7 +112,9 @@ public class BundleValidator extends BaseValidator{
|
|||
} else {
|
||||
Element res = entry.getNamedChild(RESOURCE);
|
||||
NodeStack rstack = estack.push(res, -1, null, null);
|
||||
signpost(errors, IssueType.INFORMATIONAL, res.line(), res.col(), stack.getLiteralPath(), !validator.isCrumbTrails(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM, defn.getUrl());
|
||||
if (validator.isCrumbTrails()) {
|
||||
res.addMessage(signpost(errors, IssueType.INFORMATIONAL, res.line(), res.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM, defn.getUrl()));
|
||||
}
|
||||
stack.resetIds();
|
||||
validator.startInner(hostContext, errors, res, res, defn, rstack, false);
|
||||
}
|
||||
|
|
|
@ -247,8 +247,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
if (warning(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd != null, I18nConstants.SD_ED_TYPE_PROFILE_UNKNOWN, p)) {
|
||||
StructureDefinition t = determineBaseType(sd);
|
||||
if (t == null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
||||
throw new Error("What to do about this?");
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
||||
} else {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd.getKind() == StructureDefinitionKind.RESOURCE, I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
|
||||
}
|
||||
|
@ -260,8 +259,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
if (warning(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd != null, I18nConstants.SD_ED_TYPE_PROFILE_UNKNOWN, p)) {
|
||||
StructureDefinition t = determineBaseType(sd);
|
||||
if (t == null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
||||
throw new Error("What to do about this?");
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
||||
} else {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isInstanceOf(t, code), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
|
||||
}
|
||||
|
@ -317,7 +315,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
if (t == null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
|
||||
} else if (!VersionUtilities.isR5Ver(context.getVersion())) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(t.getType()) || "Resource".equals(t), I18nConstants.SD_ED_TYPE_PROFILE_WRONG_TARGET, p, t, code, path, "Canonical Resource");
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(t.getType()) || "Resource".equals(t.getType()), I18nConstants.SD_ED_TYPE_PROFILE_WRONG_TARGET, p, t, code, path, "Canonical Resource");
|
||||
} else {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(t.getType()), I18nConstants.SD_ED_TYPE_PROFILE_WRONG_TARGET, p, t, code, path, "Canonical Resource");
|
||||
}
|
||||
|
|
|
@ -71,9 +71,12 @@ public class ChildIterator {
|
|||
String na = cursor >= parent.getChildren().size() - 1 ? "--" : parent.getChildren().get(cursor + 1).getName();
|
||||
if (name().equals(nb) || name().equals(na)) {
|
||||
return lastCount;
|
||||
} else
|
||||
} else if (element().isBaseList()) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean next() {
|
||||
if (cursor == -1) {
|
||||
|
|
|
@ -34,7 +34,7 @@ public class NodeStack {
|
|||
this.context = context;
|
||||
ids = new HashMap<>();
|
||||
this.element = element;
|
||||
literalPath = element.getName();
|
||||
literalPath = element.getPath();
|
||||
workingLang = validationLanguage;
|
||||
if (!element.getName().equals(element.fhirType())) {
|
||||
logicalPaths = new ArrayList<>();
|
||||
|
|
Loading…
Reference in New Issue