Revert to current content on HAPI
This commit is contained in:
parent
b91b68d1a2
commit
d0df12b85f
|
@ -30,7 +30,7 @@ Resource = org.hl7.fhir.instance.model.api.IAnyResource
|
|||
Period = ca.uhn.fhir.model.api.TemporalPrecisionEnum
|
||||
Extension = org.hl7.fhir.instance.model.api.IBaseExtension, org.hl7.fhir.instance.model.api.IBaseDatatype, org.hl7.fhir.instance.model.api.IBaseHasExtensions
|
||||
HumanName = ca.uhn.fhir.util.DatatypeUtil, org.hl7.fhir.instance.model.api.IPrimitiveType
|
||||
StructureMap = org.hl7.fhir.r5.utils.StructureMapUtilities
|
||||
StructureMap = org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities
|
||||
Narrative = org.hl7.fhir.instance.model.api.INarrative
|
||||
Coding = org.hl7.fhir.instance.model.api.IBaseCoding
|
||||
OperationOutcome = org.hl7.fhir.instance.model.api.IBaseOperationOutcome
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.2.8-SNAPSHOT</version>
|
||||
<version>5.2.21-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -510,7 +510,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (sd == null) {
|
||||
throw new DefinitionException("Unable to find Structure "+url);
|
||||
}
|
||||
return getChildList(sd, e.getContentReference().substring(e.getContentReference().indexOf("#")+1), null, diff);
|
||||
return getChildList(sd, e.getContentReference().substring(e.getContentReference().indexOf("#")+1), null, diff);
|
||||
} else {
|
||||
return getChildList(profile, e.getContentReference(), null, diff);
|
||||
}
|
||||
|
@ -3333,7 +3333,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(gen.new Piece("#"+ed.getElement().getPath(), tail(ed.getElement().getPath()), ed.getElement().getPath()));
|
||||
} else {
|
||||
c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null));
|
||||
c.getPieces().add(gen.new Piece(corePath+ed.getSource().getUserString("path")+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getType()+")", ed.getElement().getPath()));
|
||||
c.getPieces().add(gen.new Piece(pfx(corePath, ed.getSource().getUserString("path"))+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getType()+")", ed.getElement().getPath()));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
|
@ -6518,7 +6518,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
public ElementDefinitionResolution resolveContentRef(StructureDefinition structure, ElementDefinition element) {
|
||||
return getElementById(structure, structure.getSnapshot().getElement(), element.getContentReference());
|
||||
return getElementById(structure, structure.getSnapshot().getElement(), element.getContentReference());
|
||||
}
|
||||
|
||||
}
|
|
@ -1055,23 +1055,25 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
String display = null;
|
||||
TerminologyServiceErrorClass err = TerminologyServiceErrorClass.UNKNOWN;
|
||||
for (ParametersParameterComponent p : pOut.getParameter()) {
|
||||
if (p.getName().equals("result")) {
|
||||
ok = ((BooleanType) p.getValue()).getValue().booleanValue();
|
||||
} else if (p.getName().equals("message")) {
|
||||
message = ((StringType) p.getValue()).getValue();
|
||||
} else if (p.getName().equals("display")) {
|
||||
display = ((StringType) p.getValue()).getValue();
|
||||
} else if (p.getName().equals("cause")) {
|
||||
try {
|
||||
IssueType it = IssueType.fromCode(((StringType) p.getValue()).getValue());
|
||||
if (it == IssueType.UNKNOWN) {
|
||||
err = TerminologyServiceErrorClass.UNKNOWN;
|
||||
} else if (it == IssueType.NOTFOUND) {
|
||||
err = TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED;
|
||||
} else if (it == IssueType.NOTSUPPORTED) {
|
||||
err = TerminologyServiceErrorClass.VALUESET_UNSUPPORTED;
|
||||
if (p.hasValue()) {
|
||||
if (p.getName().equals("result")) {
|
||||
ok = ((BooleanType) p.getValue()).getValue().booleanValue();
|
||||
} else if (p.getName().equals("message")) {
|
||||
message = ((StringType) p.getValue()).getValue();
|
||||
} else if (p.getName().equals("display")) {
|
||||
display = ((StringType) p.getValue()).getValue();
|
||||
} else if (p.getName().equals("cause")) {
|
||||
try {
|
||||
IssueType it = IssueType.fromCode(((StringType) p.getValue()).getValue());
|
||||
if (it == IssueType.UNKNOWN) {
|
||||
err = TerminologyServiceErrorClass.UNKNOWN;
|
||||
} else if (it == IssueType.NOTFOUND) {
|
||||
err = TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED;
|
||||
} else if (it == IssueType.NOTSUPPORTED) {
|
||||
err = TerminologyServiceErrorClass.VALUESET_UNSUPPORTED;
|
||||
}
|
||||
} catch (FHIRException e) {
|
||||
}
|
||||
} catch (FHIRException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,16 +38,13 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
import org.hl7.fhir.r5.model.Enumerations.*;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.instance.model.api.ICompositeType;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.api.annotation.SearchParamDefinition;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ChildOrder;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
|
||||
import org.hl7.fhir.r5.utils.StructureMapUtilities;
|
||||
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
|
||||
/**
|
||||
* A Map of relationships between 2 structures that can be used to transform data.
|
||||
*/
|
||||
|
|
|
@ -62,7 +62,7 @@ public class BundleRenderer extends ResourceRenderer {
|
|||
public boolean render(XhtmlNode x, ResourceWrapper b) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
List<BaseWrapper> entries = b.children("entry");
|
||||
if ("document".equals(b.get("type").primitiveValue())) {
|
||||
if (entries.isEmpty() || (entries.get(0).has("resource") && "Composition".equals(entries.get(0).get("resource").fhirType())))
|
||||
if (entries.isEmpty() || (entries.get(0).has("resource") && !"Composition".equals(entries.get(0).get("resource").fhirType())))
|
||||
throw new FHIRException("Invalid document '"+b.getId()+"' - first entry is not a Composition ('"+entries.get(0).get("resource").fhirType()+"')");
|
||||
return renderDocument(x, b, entries);
|
||||
} else if ("collection".equals(b.get("type").primitiveValue()) && allEntriesAreHistoryProvenance(entries)) {
|
||||
|
@ -119,7 +119,7 @@ public class BundleRenderer extends ResourceRenderer {
|
|||
// * The subject resource Narrative
|
||||
// * The Composition resource Narrative
|
||||
// * The section.text Narratives
|
||||
ResourceWrapper comp = (ResourceWrapper) entries.get(0).getChildByName("resource").getValues().get(0);
|
||||
ResourceWrapper comp = (ResourceWrapper) entries.get(0).getChildByName("resource").getAsResource();
|
||||
ResourceWrapper subject = resolveReference(entries, comp.get("subject"));
|
||||
if (subject != null) {
|
||||
if (subject.hasNarrative()) {
|
||||
|
@ -175,7 +175,7 @@ public class BundleRenderer extends ResourceRenderer {
|
|||
if (entry.has("fullUrl")) {
|
||||
String fu = entry.get("fullUrl").primitiveValue();
|
||||
if (ref.equals(fu)) {
|
||||
return (ResourceWrapper) entry.getChildByName("resource").getValues().get(0);
|
||||
return (ResourceWrapper) entry.getChildByName("resource").getAsResource();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,8 +400,10 @@ public class DataRenderer extends Renderer {
|
|||
} else {
|
||||
if (uri.getValue().contains("|")) {
|
||||
x.ah(uri.getValue().substring(0, uri.getValue().indexOf("|"))).addText(uri.getValue());
|
||||
} else {
|
||||
} else if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("ftp:")) {
|
||||
x.ah(uri.getValue()).addText(uri.getValue());
|
||||
} else {
|
||||
x.code().addText(uri.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,8 +75,11 @@ public class ParametersRenderer extends ResourceRenderer {
|
|||
for (int i = 0; i < indent; i++) {
|
||||
td.tx(XhtmlNode.NBSP);
|
||||
}
|
||||
td.tx(p.get("name").primitiveValue());
|
||||
// Grahame: p.has("value") doesn't fire because the property names are things like valueString or valueBoolean and has("value") doesn't find those.
|
||||
if (p.has("name")) {
|
||||
td.tx(p.get("name").primitiveValue());
|
||||
} else {
|
||||
td.tx("???");
|
||||
}
|
||||
if (p.has("value")) {
|
||||
renderBase(tr.td(), p.get("value"));
|
||||
} else if (p.has("resource")) {
|
||||
|
|
|
@ -709,8 +709,9 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (i.hasAnswerValueSet()) {
|
||||
ValueSet vs = null;
|
||||
if (i.getAnswerValueSet().startsWith("#")) {
|
||||
vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1)).copy();
|
||||
vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
|
||||
if (vs != null && !vs.hasUrl()) {
|
||||
vs = vs.copy();
|
||||
vs.setUrl("urn:uuid:"+UUID.randomUUID().toString().toLowerCase());
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -6,8 +6,10 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ElementDefinitionResolution;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.elementmodel.XmlParser;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
|
@ -285,8 +287,9 @@ public class ElementWrappers {
|
|||
public List<BaseWrapper> getValues() {
|
||||
if (list == null) {
|
||||
list = new ArrayList<BaseWrapper>();
|
||||
for (Element e : values)
|
||||
list.add(new BaseWrapperMetaElement(context, e, e.fhirType(), structure, definition));
|
||||
for (Element e : values) {
|
||||
list.add(new BaseWrapperMetaElement(context, e, e.fhirType(), structure, definition));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ public class FHIRLexer {
|
|||
}
|
||||
|
||||
public FHIRLexerException error(String msg, String location) {
|
||||
return new FHIRLexerException("Error in "+name+" at "+location+": "+msg);
|
||||
return new FHIRLexerException("Error @"+location+": "+msg);
|
||||
}
|
||||
|
||||
public void next() throws FHIRLexerException {
|
||||
|
|
|
@ -109,7 +109,7 @@ public interface IResourceValidator {
|
|||
|
||||
Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException;
|
||||
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, String type) throws IOException, FHIRException;
|
||||
|
||||
byte[] fetchRaw(String url) throws MalformedURLException, IOException; // for attachment checking
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleComponent;
|
|||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleDependentComponent;
|
||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleSourceComponent;
|
||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleTargetComponent;
|
||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupTypeMode;
|
||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapTransform;
|
||||
import org.hl7.fhir.r5.model.UrlType;
|
||||
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
|
||||
import org.hl7.fhir.utilities.CSVReader;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,99 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.TypeDetails;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FFHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
|
||||
|
||||
private final StructureMapUtilities structureMapUtilities;
|
||||
|
||||
public FFHIRPathHostServices(StructureMapUtilities structureMapUtilities) {
|
||||
this.structureMapUtilities = structureMapUtilities;
|
||||
}
|
||||
|
||||
public Base resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException {
|
||||
Variables vars = (Variables) appContext;
|
||||
Base res = vars.get(VariableMode.INPUT, name);
|
||||
if (res == null)
|
||||
res = vars.get(VariableMode.OUTPUT, name);
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException {
|
||||
if (!(appContext instanceof VariablesForProfiling))
|
||||
throw new Error("Internal Logic Error (wrong type '" + appContext.getClass().getName() + "' in resolveConstantType)");
|
||||
VariablesForProfiling vars = (VariablesForProfiling) appContext;
|
||||
VariableForProfiling v = vars.get(null, name);
|
||||
if (v == null)
|
||||
throw new PathEngineException("Unknown variable '" + name + "' from variables " + vars.summary());
|
||||
return v.getProperty().getTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean log(String argument, List<Base> focus) {
|
||||
throw new Error("Not Implemented Yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionDetails resolveFunction(String functionName) {
|
||||
return null; // throw new Error("Not Implemented Yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) throws PathEngineException {
|
||||
throw new Error("Not Implemented Yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Base> executeFunction(Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
|
||||
throw new Error("Not Implemented Yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
|
||||
if (structureMapUtilities.getServices() == null)
|
||||
return null;
|
||||
return structureMapUtilities.getServices().resolveReference(appContext, url);
|
||||
}
|
||||
|
||||
private boolean noErrorValidationMessages(List<ValidationMessage> valerrors) {
|
||||
boolean ok = true;
|
||||
for (ValidationMessage v : valerrors)
|
||||
ok = ok && !v.getLevel().isError();
|
||||
return ok;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
|
||||
IResourceValidator val = structureMapUtilities.getWorker().newValidator();
|
||||
List<ValidationMessage> valerrors = new ArrayList<ValidationMessage>();
|
||||
if (item instanceof Resource) {
|
||||
val.validate(appContext, valerrors, (Resource) item, url);
|
||||
return noErrorValidationMessages(valerrors);
|
||||
}
|
||||
if (item instanceof Element) {
|
||||
val.validate(appContext, valerrors, (Element) item, url);
|
||||
return noErrorValidationMessages(valerrors);
|
||||
}
|
||||
throw new NotImplementedException("Not done yet (FFHIRPathHostServices.conformsToProfile), when item is not element or not resource");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet resolveValueSet(Object appContext, String url) {
|
||||
throw new Error("Not Implemented Yet");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ITransformerServices {
|
||||
// public boolean validateByValueSet(Coding code, String valuesetId);
|
||||
public void log(String message); // log internal progress
|
||||
|
||||
public Base createType(Object appInfo, String name) throws FHIRException;
|
||||
|
||||
public Base createResource(Object appInfo, Base res, boolean atRootofTransform); // an already created resource is provided; this is to identify/store it
|
||||
|
||||
public Coding translate(Object appInfo, Coding source, String conceptMapUrl) throws FHIRException;
|
||||
|
||||
// public Coding translate(Coding code)
|
||||
// ValueSet validation operation
|
||||
// Translation operation
|
||||
// Lookup another tree of data
|
||||
// Create an instance tree
|
||||
// Return the correct string format to refer to a tree (input or output)
|
||||
public Base resolveReference(Object appContext, String url) throws FHIRException;
|
||||
|
||||
public List<Base> performSearch(Object appContext, String url) throws FHIRException;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.r5.elementmodel.Property;
|
||||
import org.hl7.fhir.r5.model.TypeDetails;
|
||||
|
||||
public class PropertyWithType {
|
||||
private String path;
|
||||
private Property baseProperty;
|
||||
private Property profileProperty;
|
||||
private TypeDetails types;
|
||||
|
||||
public PropertyWithType(String path, Property baseProperty, Property profileProperty, TypeDetails types) {
|
||||
super();
|
||||
this.baseProperty = baseProperty;
|
||||
this.profileProperty = profileProperty;
|
||||
this.path = path;
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public TypeDetails getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public Property getBaseProperty() {
|
||||
return baseProperty;
|
||||
}
|
||||
|
||||
public void setBaseProperty(Property baseProperty) {
|
||||
this.baseProperty = baseProperty;
|
||||
}
|
||||
|
||||
public Property getProfileProperty() {
|
||||
return profileProperty;
|
||||
}
|
||||
|
||||
public void setProfileProperty(Property profileProperty) {
|
||||
this.profileProperty = profileProperty;
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.r5.model.StructureMap;
|
||||
|
||||
public class ResolvedGroup {
|
||||
public StructureMap.StructureMapGroupComponent target;
|
||||
public StructureMap targetMap;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
|
||||
public class SourceElementComponentWrapper {
|
||||
private ConceptMap.ConceptMapGroupComponent group;
|
||||
private ConceptMap.SourceElementComponent comp;
|
||||
|
||||
public SourceElementComponentWrapper(ConceptMap.ConceptMapGroupComponent group, ConceptMap.SourceElementComponent comp) {
|
||||
super();
|
||||
this.group = group;
|
||||
this.comp = comp;
|
||||
}
|
||||
|
||||
public ConceptMap.ConceptMapGroupComponent getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public ConceptMap.SourceElementComponent getComp() {
|
||||
return comp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
public class StringPair {
|
||||
private String var;
|
||||
private String desc;
|
||||
|
||||
public StringPair(String var, String desc) {
|
||||
super();
|
||||
this.var = var;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getVar() {
|
||||
return var;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StructureMapAnalysis {
|
||||
public List<StructureDefinition> profiles = new ArrayList<StructureDefinition>();
|
||||
public XhtmlNode summary;
|
||||
|
||||
public List<StructureDefinition> getProfiles() {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public XhtmlNode getSummary() {
|
||||
return summary;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TargetWriter {
|
||||
private Map<String, String> newResources = new HashMap<String, String>();
|
||||
private List<StringPair> assignments = new ArrayList<StringPair>();
|
||||
private List<StringPair> keyProps = new ArrayList<StringPair>();
|
||||
private CommaSeparatedStringBuilder txt = new CommaSeparatedStringBuilder();
|
||||
|
||||
public void newResource(String var, String name) {
|
||||
newResources.put(var, name);
|
||||
txt.append("new " + name);
|
||||
}
|
||||
|
||||
public void valueAssignment(String context, String desc) {
|
||||
assignments.add(new StringPair(context, desc));
|
||||
txt.append(desc);
|
||||
}
|
||||
|
||||
public void keyAssignment(String context, String desc) {
|
||||
keyProps.add(new StringPair(context, desc));
|
||||
txt.append(desc);
|
||||
}
|
||||
|
||||
public void commit(XhtmlNode xt) {
|
||||
if (newResources.size() == 1 && assignments.size() == 1 && newResources.containsKey(assignments.get(0).getVar()) && keyProps.size() == 1 && newResources.containsKey(keyProps.get(0).getVar())) {
|
||||
xt.addText("new " + assignments.get(0).getDesc() + " (" + keyProps.get(0).getDesc().substring(keyProps.get(0).getDesc().indexOf(".") + 1) + ")");
|
||||
} else if (newResources.size() == 1 && assignments.size() == 1 && newResources.containsKey(assignments.get(0).getVar()) && keyProps.size() == 0) {
|
||||
xt.addText("new " + assignments.get(0).getDesc());
|
||||
} else {
|
||||
xt.addText(txt.toString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
public class TransformContext {
|
||||
private Object appInfo;
|
||||
|
||||
public TransformContext(Object appInfo) {
|
||||
super();
|
||||
this.appInfo = appInfo;
|
||||
}
|
||||
|
||||
public Object getAppInfo() {
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
|
||||
public class Variable {
|
||||
private VariableMode mode;
|
||||
private String name;
|
||||
private Base object;
|
||||
|
||||
public Variable(VariableMode mode, String name, Base object) {
|
||||
super();
|
||||
this.mode = mode;
|
||||
this.name = name;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public VariableMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Base getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
if (object == null)
|
||||
return null;
|
||||
else if (object instanceof PrimitiveType)
|
||||
return name + ": \"" + ((PrimitiveType) object).asStringValue() + '"';
|
||||
else
|
||||
return name + ": (" + object.fhirType() + ")";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
public class VariableForProfiling {
|
||||
private VariableMode mode;
|
||||
private String name;
|
||||
private PropertyWithType property;
|
||||
|
||||
public VariableForProfiling(VariableMode mode, String name, PropertyWithType property) {
|
||||
super();
|
||||
this.mode = mode;
|
||||
this.name = name;
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
public VariableMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public PropertyWithType getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
return name + ": " + property.summary();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
public enum VariableMode {
|
||||
INPUT, OUTPUT, SHARED
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Variables {
|
||||
private List<Variable> list = new ArrayList<Variable>();
|
||||
|
||||
public void add(VariableMode mode, String name, Base object) {
|
||||
Variable vv = null;
|
||||
for (Variable v : list)
|
||||
if ((v.getMode() == mode) && v.getName().equals(name))
|
||||
vv = v;
|
||||
if (vv != null)
|
||||
list.remove(vv);
|
||||
list.add(new Variable(mode, name, object));
|
||||
}
|
||||
|
||||
public Variables copy() {
|
||||
Variables result = new Variables();
|
||||
result.list.addAll(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Base get(VariableMode mode, String name) {
|
||||
for (Variable v : list)
|
||||
if ((v.getMode() == mode) && v.getName().equals(name))
|
||||
return v.getObject();
|
||||
return null;
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
CommaSeparatedStringBuilder s = new CommaSeparatedStringBuilder();
|
||||
CommaSeparatedStringBuilder t = new CommaSeparatedStringBuilder();
|
||||
CommaSeparatedStringBuilder sh = new CommaSeparatedStringBuilder();
|
||||
for (Variable v : list)
|
||||
switch (v.getMode()) {
|
||||
case INPUT:
|
||||
s.append(v.summary());
|
||||
break;
|
||||
case OUTPUT:
|
||||
t.append(v.summary());
|
||||
break;
|
||||
case SHARED:
|
||||
sh.append(v.summary());
|
||||
break;
|
||||
}
|
||||
return "source variables [" + s.toString() + "], target variables [" + t.toString() + "], shared variables [" + sh.toString() + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package org.hl7.fhir.r5.utils.structuremap;
|
||||
|
||||
import org.hl7.fhir.r5.elementmodel.Property;
|
||||
import org.hl7.fhir.r5.model.TypeDetails;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VariablesForProfiling {
|
||||
private final StructureMapUtilities structureMapUtilities;
|
||||
private List<VariableForProfiling> list = new ArrayList<VariableForProfiling>();
|
||||
private boolean optional;
|
||||
private boolean repeating;
|
||||
|
||||
public VariablesForProfiling(StructureMapUtilities structureMapUtilities, boolean optional, boolean repeating) {
|
||||
this.structureMapUtilities = structureMapUtilities;
|
||||
this.optional = optional;
|
||||
this.repeating = repeating;
|
||||
}
|
||||
|
||||
public void add(VariableMode mode, String name, String path, Property property, TypeDetails types) {
|
||||
add(mode, name, new PropertyWithType(path, property, null, types));
|
||||
}
|
||||
|
||||
public void add(VariableMode mode, String name, String path, Property baseProperty, Property profileProperty, TypeDetails types) {
|
||||
add(mode, name, new PropertyWithType(path, baseProperty, profileProperty, types));
|
||||
}
|
||||
|
||||
public void add(VariableMode mode, String name, PropertyWithType property) {
|
||||
VariableForProfiling vv = null;
|
||||
for (VariableForProfiling v : list)
|
||||
if ((v.getMode() == mode) && v.getName().equals(name))
|
||||
vv = v;
|
||||
if (vv != null)
|
||||
list.remove(vv);
|
||||
list.add(new VariableForProfiling(mode, name, property));
|
||||
}
|
||||
|
||||
public VariablesForProfiling copy(boolean optional, boolean repeating) {
|
||||
VariablesForProfiling result = new VariablesForProfiling(structureMapUtilities, optional, repeating);
|
||||
result.list.addAll(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
public VariablesForProfiling copy() {
|
||||
VariablesForProfiling result = new VariablesForProfiling(structureMapUtilities, optional, repeating);
|
||||
result.list.addAll(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
public VariableForProfiling get(VariableMode mode, String name) {
|
||||
if (mode == null) {
|
||||
for (VariableForProfiling v : list)
|
||||
if ((v.getMode() == VariableMode.OUTPUT) && v.getName().equals(name))
|
||||
return v;
|
||||
for (VariableForProfiling v : list)
|
||||
if ((v.getMode() == VariableMode.INPUT) && v.getName().equals(name))
|
||||
return v;
|
||||
}
|
||||
for (VariableForProfiling v : list)
|
||||
if ((v.getMode() == mode) && v.getName().equals(name))
|
||||
return v;
|
||||
return null;
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
CommaSeparatedStringBuilder s = new CommaSeparatedStringBuilder();
|
||||
CommaSeparatedStringBuilder t = new CommaSeparatedStringBuilder();
|
||||
for (VariableForProfiling v : list)
|
||||
if (v.getMode() == VariableMode.INPUT)
|
||||
s.append(v.summary());
|
||||
else
|
||||
t.append(v.summary());
|
||||
return "source variables [" + s.toString() + "], target variables [" + t.toString() + "]";
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package org.hl7.fhir.r5.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
|
@ -10,18 +7,21 @@ import org.hl7.fhir.r5.model.Coding;
|
|||
import org.hl7.fhir.r5.model.StructureMap;
|
||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleTargetComponent;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.r5.utils.StructureMapUtilities;
|
||||
import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices;
|
||||
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
|
||||
import org.hl7.fhir.r5.utils.structuremap.ITransformerServices;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.ToolsVersion;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class StructureMapUtilitiesTest implements ITransformerServices {
|
||||
|
||||
static private SimpleWorkerContext context;
|
||||
|
||||
|
||||
@BeforeAll
|
||||
static public void setUp() throws Exception {
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
|
@ -37,10 +37,7 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
// StructureMap/ActivityDefinition3to4: StructureMap.group[3].rule[2].name error id value '"expression"' is not valid
|
||||
Assertions.assertEquals("expression", structureMap.getGroup().get(2).getRule().get(1).getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void assertSerializeDeserialize(StructureMap structureMap) {
|
||||
Assertions.assertEquals("syntax", structureMap.getName());
|
||||
Assertions.assertEquals("Title of this map\r\nAuthor", structureMap.getDescription());
|
||||
|
@ -54,7 +51,7 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
Assertions.assertEquals("Groups\r\nrule for patient group", structureMap.getGroup().get(0).getDocumentation());
|
||||
Assertions.assertEquals("Comment to rule", structureMap.getGroup().get(0).getRule().get(0).getDocumentation());
|
||||
Assertions.assertEquals("Copy identifier short syntax", structureMap.getGroup().get(0).getRule().get(1).getDocumentation());
|
||||
|
||||
|
||||
StructureMapGroupRuleTargetComponent target = structureMap.getGroup().get(0).getRule().get(2).getTarget().get(1);
|
||||
Assertions.assertEquals("'urn:uuid:' + r.lower()", target.getParameter().get(0).toString());
|
||||
}
|
||||
|
@ -67,13 +64,13 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
|
||||
StructureMap structureMap = scu.parse(fileMap, "Syntax");
|
||||
assertSerializeDeserialize(structureMap);
|
||||
|
||||
|
||||
String renderedMap = StructureMapUtilities.render(structureMap);
|
||||
StructureMap map = scu.parse(renderedMap, "Syntax");
|
||||
System.out.println(map);
|
||||
assertSerializeDeserialize(map);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
}
|
||||
|
@ -102,5 +99,4 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
public List<Base> performSearch(Object appContext, String url) throws FHIRException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -639,7 +639,7 @@ public class Utilities {
|
|||
return false;
|
||||
}
|
||||
File tmp = new File("c:\\temp");
|
||||
return tmp.exists() && tmp.isDirectory();
|
||||
return tmp.exists() && tmp.isDirectory() && tmp.canWrite();
|
||||
}
|
||||
|
||||
public static String pathURL(String... args) {
|
||||
|
@ -1090,7 +1090,8 @@ public class Utilities {
|
|||
|
||||
|
||||
public static boolean isAbsoluteUrl(String ref) {
|
||||
return ref != null && (ref.startsWith("http:") || ref.startsWith("https:") || ref.startsWith("urn:uuid:") || ref.startsWith("urn:oid:"));
|
||||
return ref != null && (ref.startsWith("http:") || ref.startsWith("https:") || ref.startsWith("urn:uuid:") || ref.startsWith("urn:oid:") ||
|
||||
Utilities.startsWithInList(ref, "urn:iso:", "urn:iso-iec:", "urn:iso-cie:", "urn:iso-astm:", "urn:iso-ieee:", "urn:iec:")); // rfc5141
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -364,6 +364,7 @@ public class VersionUtilities {
|
|||
res.add("TestScript");
|
||||
}
|
||||
if (isR3Ver(version)) {
|
||||
res.add("CodeSystem");
|
||||
res.add("CapabilityStatement");
|
||||
res.add("StructureDefinition");
|
||||
res.add("ImplementationGuide");
|
||||
|
@ -388,6 +389,7 @@ public class VersionUtilities {
|
|||
}
|
||||
if (isR4Ver(version)) {
|
||||
|
||||
res.add("CodeSystem");
|
||||
res.add("ActivityDefinition");
|
||||
res.add("CapabilityStatement");
|
||||
res.add("ChargeItemDefinition");
|
||||
|
@ -419,7 +421,7 @@ public class VersionUtilities {
|
|||
res.add("ValueSet");
|
||||
}
|
||||
|
||||
if (isR5Ver(version)) {
|
||||
if (isR5Ver(version) || "current".equals(version)) {
|
||||
|
||||
res.add("ActivityDefinition");
|
||||
res.add("CapabilityStatement");
|
||||
|
|
|
@ -48,7 +48,7 @@ public class I18nConstants {
|
|||
public static final String CODESYSTEM_CS_NO_VS_NOTCOMPLETE = "CODESYSTEM_CS_NO_VS_NOTCOMPLETE";
|
||||
public static final String CODESYSTEM_CS_VS_INCLUDEDETAILS = "CodeSystem_CS_VS_IncludeDetails";
|
||||
public static final String CODESYSTEM_CS_VS_INVALID = "CodeSystem_CS_VS_Invalid";
|
||||
public static final String CODESYSTEM_CS_VS_MISMATCH = "CodeSystem_CS_VS_MisMatch";
|
||||
public static final String CODESYSTEM_CS_VS_EXP_MISMATCH = "CODESYSTEM_CS_VS_EXP_MISMATCH";
|
||||
public static final String CODESYSTEM_CS_VS_WRONGSYSTEM = "CodeSystem_CS_VS_WrongSystem";
|
||||
public static final String CODESYSTEM_CS_NO_SUPPLEMENT = "CODESYSTEM_CS_NO_SUPPLEMENT";
|
||||
public static final String CODESYSTEM_CS_SUPP_CANT_CHECK = "CODESYSTEM_CS_SUPP_CANT_CHECK";
|
||||
|
@ -70,6 +70,7 @@ public class I18nConstants {
|
|||
public static final String DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0 = "Discriminator__is_based_on_element_existence_but_slice__neither_sets_min1_or_max0";
|
||||
public static final String DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_ = "Discriminator__is_based_on_type_but_slice__in__has_multiple_types_";
|
||||
public static final String DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES = "Discriminator__is_based_on_type_but_slice__in__has_no_types";
|
||||
public static final String DISCRIMINATOR_BAD_PATH = "DISCRIMINATOR_BAD_PATH";
|
||||
public static final String DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF_ = "Display_Name_for__should_be_one_of__instead_of_";
|
||||
public static final String DOCUMENT = "documentmsg";
|
||||
public static final String DOCUMENT_DATE_REQUIRED = "Bundle_Document_Date_Missing";
|
||||
|
@ -80,6 +81,7 @@ public class I18nConstants {
|
|||
public static final String ELEMENT_ID__NULL__ON_ = "element_id__null__on_";
|
||||
public static final String ELEMENT_MUST_HAVE_SOME_CONTENT = "Element_must_have_some_content";
|
||||
public static final String ELEMENT__NULL_ = "element__null_";
|
||||
public static final String SLICING_CANNOT_BE_EVALUATED = "SLICING_CANNOT_BE_EVALUATED";
|
||||
public static final String ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORCOUNT__1 = "Error_at_path__in__Type_slicing_with_slicingdiscriminatorcount__1";
|
||||
public static final String ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORPATH__THIS = "Error_at_path__in__Type_slicing_with_slicingdiscriminatorpath__this";
|
||||
public static final String ERROR_AT_PATH__IN__TYPE_SLICING_WITH_SLICINGDISCRIMINATORTYPE__TYPE = "Error_at_path__in__Type_slicing_with_slicingdiscriminatortype__type";
|
||||
|
@ -183,7 +185,6 @@ 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 = "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_";
|
||||
|
@ -353,7 +354,13 @@ public class I18nConstants {
|
|||
public static final String SD_ED_TYPE_PROFILE_UNKNOWN = "SD_ED_TYPE_PROFILE_UNKNOWN";
|
||||
public static final String SD_ED_TYPE_PROFILE_NOTYPE = "SD_ED_TYPE_PROFILE_NOTYPE";
|
||||
public static final String SD_ED_TYPE_PROFILE_WRONG = "SD_ED_TYPE_PROFILE_WRONG";
|
||||
public static final String SD_ED_TYPE_PROFILE_WRONG_TARGET = "SD_ED_TYPE_PROFILE_WRONG_TARGET";
|
||||
public static final String SD_ED_TYPE_NO_TARGET_PROFILE = "SD_ED_TYPE_NO_TARGET_PROFILE";
|
||||
public static final String SD_ED_SHOULD_BIND = "SD_ED_SHOULD_BIND";
|
||||
public static final String SD_ED_SHOULD_BIND_WITH_VS = "SD_ED_SHOULD_BIND_WITH_VS";
|
||||
public static final String SD_ED_BIND_UNKNOWN_VS = "SD_ED_BIND_UNKNOWN_VS";
|
||||
public static final String SD_ED_BIND_NOT_VS = "SD_ED_BIND_NOT_VS";
|
||||
public static final String SD_ED_BIND_NO_BINDABLE = "SD_ED_BIND_NO_BINDABLE";
|
||||
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";
|
||||
|
@ -488,6 +495,8 @@ public class I18nConstants {
|
|||
public static final String TYPE_SPECIFIC_CHECKS_DT_URI_UUID = "Type_Specific_Checks_DT_URI_UUID";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_URI_WS = "Type_Specific_Checks_DT_URI_WS";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE = "Type_Specific_Checks_DT_URL_Resolve";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE = "TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE = "TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_UUID_STRAT = "Type_Specific_Checks_DT_UUID_Strat";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_UUID_VAID = "Type_Specific_Checks_DT_UUID_Vaid";
|
||||
public static final String UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER = "Unable_to_connect_to_terminology_server";
|
||||
|
@ -595,6 +604,11 @@ public class I18nConstants {
|
|||
public static final String XHTML_URL_EMPTY = "XHTML_URL_EMPTY";
|
||||
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_URL_DATA_NO_DATA = "XHTML_URL_DATA_NO_DATA";
|
||||
public static final String XHTML_URL_DATA_DATA_INVALID_COMMA = "XHTML_URL_DATA_DATA_INVALID_COMMA";
|
||||
public static final String XHTML_URL_DATA_DATA_INVALID = "XHTML_URL_DATA_DATA_INVALID";
|
||||
public static final String XHTML_URL_DATA_MIMETYPE = "XHTML_URL_DATA_MIMETYPE";
|
||||
|
||||
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";
|
||||
|
|
|
@ -106,8 +106,8 @@ Questionnaire_Q_EnableWhen_Self = Target for this question enableWhen can''t ref
|
|||
Reference_REF_Aggregation = Reference is {0} which isn''t supported by the specified aggregation mode(s) for the reference ({1})
|
||||
Reference_REF_BadTargetType = Invalid Resource target type. Found {0}, but expected one of ({1})
|
||||
Reference_REF_BadTargetType2 = The type ''{0}'' implied by the reference URL {1} is not a valid Target for this element (must be one of {2})
|
||||
Reference_REF_CantMatchChoice = Unable to find matching profile for {0} among choices: {1}
|
||||
Reference_REF_CantMatchType = Unable to find matching profile for {0} (by type) among choices: {1}
|
||||
Reference_REF_CantMatchChoice = Unable to find a match for profile {0} among choices: {1}
|
||||
Reference_REF_CantMatchType = Unable to find a match for profile {0} (by type) among choices: {1}
|
||||
Reference_REF_CantResolve = Unable to resolve resource ''{0}''
|
||||
Reference_REF_CantResolveProfile = Unable to resolve the profile reference ''{0}''
|
||||
Reference_REF_Format1 = Relative URLs must be of the format [ResourceName]/[id], or a search URL is allowed ([type]?parameters. Encountered {0})
|
||||
|
@ -153,7 +153,7 @@ Terminology_TX_NoValid_13 = The Coding provided ({2}) is not in the value set {0
|
|||
Terminology_TX_NoValid_14 = The Coding provided ({2}) 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}
|
||||
Terminology_TX_NoValid_17 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable){3}
|
||||
Terminology_TX_NoValid_17 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable) {3}
|
||||
Terminology_TX_NoValid_18 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code is recommended to come from this value set){3}
|
||||
Terminology_TX_NoValid_2 = None of the codes provided are in the value set {0} ({1}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable) (codes = {2})
|
||||
Terminology_TX_NoValid_3 = None of the codes provided are in the value set {0} ({1}), and a code is recommended to come from this value set) (codes = {2})
|
||||
|
@ -217,7 +217,7 @@ Validation_VAL_Profile_NoCheckMax = {2}: Unable to check max allowed ({1}) due t
|
|||
Validation_VAL_Profile_NoCheckMin = {2}: Unable to check minimum required ({1}) due to lack of slicing validation (from {0})
|
||||
Validation_VAL_Profile_MultipleMatches = Found multiple matching profiles among choices: {0}
|
||||
Validation_VAL_Profile_NoDefinition = No definition found for resource type ''{0}''
|
||||
Validation_VAL_Profile_NoMatch = Unable to find matching profile among choices: {0}
|
||||
Validation_VAL_Profile_NoMatch = Unable to find a match for the specified profile among choices: {0}
|
||||
Validation_VAL_Profile_NoSnapshot = StructureDefinition has no snapshot - validation is against the snapshot, so it must be provided
|
||||
Validation_VAL_Profile_NoType = The type of element {0} is not known, which is illegal. Valid types at this point are {1}
|
||||
Validation_VAL_Profile_NotAllowed = This element is not allowed by the profile {0}
|
||||
|
@ -367,10 +367,10 @@ Error_parsing_JSON_the_primitive_value_must_be_a_string = Error parsing JSON: th
|
|||
Error_parsing_JSON_the_primitive_value_must_be_a_number = Error parsing JSON: the primitive value must be a number
|
||||
Error_parsing_JSON_the_primitive_value_must_be_a_boolean = Error parsing JSON: the primitive value must be a boolean
|
||||
Error_parsing_XHTML_ = Error parsing XHTML: {0}
|
||||
This_property_must_be_an_object_not_ = This property must be an object, not {0}
|
||||
This_property_must_be_an_simple_value_not_ = This property must be an simple value, not {0}
|
||||
This_property_must_be__not_ = This property must be {0}, not {1}
|
||||
This_property_must_be_an_Array_not_ = This property must be an Array, not {0}
|
||||
This_property_must_be_an_object_not_ = This property must be an object, not {0} ({1} at {2})
|
||||
This_property_must_be_an_simple_value_not_ = This property must be an simple value, not {0} ({1} at {2})
|
||||
This_property_must_be__not_ = The property {2} must be {0}, not {1} (at {3})
|
||||
This_property_must_be_an_Array_not_ = The property {1} must be a JSON Array, not {0} (at {2})
|
||||
Unrecognised_property_ = Unrecognised property ''@{0}''
|
||||
Object_must_have_some_content = Object must have some content
|
||||
Error_parsing_JSON_ = Error parsing JSON: {0}
|
||||
|
@ -384,8 +384,8 @@ Element_must_have_some_content = Element must have some content
|
|||
No_processing_instructions_allowed_in_resources = No processing instructions allowed in resources
|
||||
Unknown_resource_type_missing_rdfstype = Unknown resource type (missing rdfs:type)
|
||||
reference_to__cannot_be_resolved = reference to {0} cannot be resolved
|
||||
This_property_must_be_a_URI_or_bnode_not_a_ = This property must be a URI or bnode, not a {0}
|
||||
This_property_must_be_a_Literal_not_a_ = This property must be a Literal, not a {0}
|
||||
This_property_must_be_a_URI_or_bnode_not_ = This property must be a URI or bnode, not {0}
|
||||
This_property_must_be_a_Literal_not_ = This property must be a Literal, not {0}
|
||||
Unrecognised_predicate_ = Unrecognised predicate ''{0}''
|
||||
Error_parsing_Turtle_ = Error parsing Turtle: {0}
|
||||
Unexpected_datatype_for_rdfstype = Unexpected datatype for rdfs:type
|
||||
|
@ -522,7 +522,6 @@ TYPE_CHECKS_PATTERN_CC = The pattern [system {0}, code {1}, and display ''{2}'']
|
|||
TYPE_CHECKS_PATTERN_CC_US = The pattern [system {0}, code {1}, display ''{2}'' and userSelected {5}] defined in the profile {3} not found. Issues: {4}
|
||||
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}
|
||||
Internal_error = Internal error: {0}
|
||||
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 = Validate resource against profile {0}
|
||||
VALIDATION_VAL_PROFILE_SIGNPOST_META = Validate resource against profile {0} - listed in meta
|
||||
|
@ -637,4 +636,6 @@ DISCRIMINATOR_BAD_PATH = Error processing path expression for disciminator: {0}
|
|||
SLICING_CANNOT_BE_EVALUATED = Slicing cannot be evaluated: {0}
|
||||
TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE = Canonical URL ''{0}'' does not resolve
|
||||
TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE = Canonical URL ''{0}'' refers to a resource that has the wrong type. Found {1} expecting one of {2}
|
||||
|
||||
CODESYSTEM_CS_NO_SUPPLEMENT = CodeSystem {0} is a supplement, so can't be used as a value in Coding.system
|
||||
CODESYSTEM_CS_SUPP_CANT_CHECK = CodeSystem {0} cannot be found, so can't check if concepts are valid
|
||||
CODESYSTEM_CS_SUPP_INVALID_CODE = The code ''{1}'' is not declared in the base CodeSystem {0} so is not valid in the supplement
|
||||
|
|
|
@ -205,7 +205,7 @@ Validation_VAL_Content_Unknown=Unerkannter Inhalt {0}
|
|||
Validation_VAL_NoType=Unbekannter Typ {0}
|
||||
Validation_VAL_Profile_MatchMultiple=Profil {0}, Element stimmt mit mehr als einem Slice überein - {1}, {2}
|
||||
Validation_VAL_Profile_Maximum={0}: maximal erlaubt = {1}, aber gefunden {2}
|
||||
Validation_VAL_Profile_Minimum={0}: mindestens erforderlich = {1}, aber nur gefunden {2}
|
||||
Validation_VAL_Profile_Minimum={2}: mindestens erforderlich = {6}, aber nur gefunden {7}
|
||||
Validation_VAL_Profile_MultipleMatches=Es wurden mehrere passende Profile unter den Auswahlmöglichkeiten gefunden: {0}
|
||||
Validation_VAL_Profile_NoCheckMax={0}: Kann die maximal zulässige Anzahl ({1}) aufgrund fehlender Slicing-Validierung nicht überprüfen.
|
||||
Validation_VAL_Profile_NoCheckMin={0}": Kann das erforderliche Minimum ({1}) aufgrund fehlender Slicing-Validierung nicht überprüfen
|
||||
|
|
|
@ -84,10 +84,28 @@ import org.hl7.fhir.utilities.validation.ValidationMessage;
|
|||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
||||
import org.hl7.fhir.validation.BaseValidator.TrackedLocationRelatedMessage;
|
||||
import org.hl7.fhir.validation.instance.utils.IndexedElement;
|
||||
|
||||
public class BaseValidator {
|
||||
|
||||
public class TrackedLocationRelatedMessage {
|
||||
private Object location;
|
||||
private ValidationMessage vmsg;
|
||||
public TrackedLocationRelatedMessage(Object location, ValidationMessage vmsg) {
|
||||
super();
|
||||
this.location = location;
|
||||
this.vmsg = vmsg;
|
||||
}
|
||||
public Object getLocation() {
|
||||
return location;
|
||||
}
|
||||
public ValidationMessage getVmsg() {
|
||||
return vmsg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ValidationControl {
|
||||
private boolean allowed;
|
||||
private IssueSeverity level;
|
||||
|
@ -122,8 +140,10 @@ public class BaseValidator {
|
|||
protected IWorkerContext context;
|
||||
protected TimeTracker timeTracker = new TimeTracker();
|
||||
protected XVerExtensionManager xverManager;
|
||||
|
||||
public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager) {
|
||||
protected List<TrackedLocationRelatedMessage> trackedMessages = new ArrayList<>();
|
||||
protected List<ValidationMessage> messagesToRemove = new ArrayList<>();
|
||||
|
||||
public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.xverManager = xverManager;
|
||||
|
@ -493,7 +513,38 @@ public class BaseValidator {
|
|||
return thePass;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails. Also, keep track of it later in case we want to remove it if we find a required binding for this element later
|
||||
*
|
||||
* @param thePass
|
||||
* Set this parameter to <code>false</code> if the validation does not pass
|
||||
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
|
||||
*/
|
||||
protected boolean txWarningForLaterRemoval(Object location, List<ValidationMessage> errors, String txLink, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) {
|
||||
if (!thePass) {
|
||||
String nmsg = context.formatMessage(msg, theMessageArguments);
|
||||
ValidationMessage vmsg = new ValidationMessage(Source.TerminologyEngine, type, line, col, path, nmsg, IssueSeverity.WARNING).setTxLink(txLink).setMessageId(msg);
|
||||
if (checkMsgId(msg, vmsg)) {
|
||||
errors.add(vmsg);
|
||||
}
|
||||
trackedMessages.add(new TrackedLocationRelatedMessage(location, vmsg));
|
||||
}
|
||||
return thePass;
|
||||
|
||||
}
|
||||
|
||||
protected void removeTrackedMessagesForLocation(List<ValidationMessage> errors, Object location, String path) {
|
||||
List<TrackedLocationRelatedMessage> messages = new ArrayList<>();
|
||||
for (TrackedLocationRelatedMessage m : trackedMessages) {
|
||||
if (m.getLocation() == location) {
|
||||
messages.add(m);
|
||||
messagesToRemove.add(m.getVmsg());
|
||||
}
|
||||
}
|
||||
trackedMessages.removeAll(messages);
|
||||
}
|
||||
|
||||
protected boolean warningOrError(boolean isError, List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) {
|
||||
if (!thePass) {
|
||||
String nmsg = context.formatMessage(msg, theMessageArguments);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package org.hl7.fhir.validation;
|
||||
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
|
||||
class Content {
|
||||
byte[] focus = null;
|
||||
Manager.FhirFormat cntType = null;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,49 @@
|
|||
package org.hl7.fhir.validation;
|
||||
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ValidationRecord {
|
||||
|
||||
private String location;
|
||||
private List<ValidationMessage> messages;
|
||||
int err = 0;
|
||||
int warn = 0;
|
||||
int info = 0;
|
||||
|
||||
public ValidationRecord(String location, List<ValidationMessage> messages) {
|
||||
this.location = location;
|
||||
this.messages = messages;
|
||||
for (ValidationMessage vm : messages) {
|
||||
if (vm.getLevel().equals(ValidationMessage.IssueSeverity.FATAL) || vm.getLevel().equals(ValidationMessage.IssueSeverity.ERROR))
|
||||
err++;
|
||||
else if (vm.getLevel().equals(ValidationMessage.IssueSeverity.WARNING))
|
||||
warn++;
|
||||
else if (!vm.isSignpost()) {
|
||||
info++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public int getErr() {
|
||||
return err;
|
||||
}
|
||||
|
||||
public int getWarn() {
|
||||
return warn;
|
||||
}
|
||||
|
||||
public int getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@ import java.util.List;
|
|||
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.validation.ValidationEngine.ValidationRecord;
|
||||
import org.hl7.fhir.validation.ValidationRecord;
|
||||
import org.hl7.fhir.validation.cli.utils.VersionUtil;
|
||||
|
||||
public class HTMLOutputGenerator {
|
||||
|
|
|
@ -3,6 +3,8 @@ package org.hl7.fhir.validation.cli.services;
|
|||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hl7.fhir.convertors.txClient.TerminologyClientFactory;
|
||||
|
@ -18,10 +20,16 @@ import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy;
|
|||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo;
|
||||
import org.hl7.fhir.utilities.json.JSONUtil;
|
||||
import org.hl7.fhir.utilities.json.JsonTrackingParser;
|
||||
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ca.uhn.fhir.util.JsonUtil;
|
||||
|
||||
public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
|
||||
|
||||
public interface IPackageInstaller {
|
||||
|
@ -29,6 +37,7 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
|
|||
void loadPackage(String id, String ver) throws IOException, FHIRException;
|
||||
}
|
||||
|
||||
List<String> mappingsUris = new ArrayList<>();
|
||||
private FilesystemPackageCacheManager pcm;
|
||||
private IWorkerContext context;
|
||||
private IPackageInstaller installer;
|
||||
|
@ -51,17 +60,25 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException {
|
||||
public boolean resolveURL(Object appContext, String path, String url, String type) throws IOException, FHIRException {
|
||||
if (!Utilities.isAbsoluteUrl(url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.contains("|")) {
|
||||
url = url.substring(0, url.lastIndexOf("|"));
|
||||
}
|
||||
|
||||
if (type.equals("uri") && isMappingUri(url)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if we've got to here, it's a reference to a FHIR URL. We're going to try to resolve it on the fly
|
||||
String pid = null;
|
||||
String ver = null;
|
||||
String base = findBaseUrl(url);
|
||||
if (base == null) {
|
||||
return false;
|
||||
return !url.startsWith("http://hl7.org/fhir") && !type.equals("canonical");
|
||||
}
|
||||
|
||||
if (base.equals("http://terminology.hl7.org")) {
|
||||
|
@ -72,7 +89,7 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
|
|||
pid = pcm.findCanonicalInLocalCache(base);
|
||||
}
|
||||
ver = url.contains("|") ? url.substring(url.indexOf("|")+1) : null;
|
||||
if (pid == null) {
|
||||
if (pid == null && Utilities.startsWithInList(url, "http://hl7.org/fhir", "http://terminology.hl7.org")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -94,8 +111,68 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// we don't bother with urls outside fhir space in the standalone validator - we assume they are valid
|
||||
return !url.startsWith("http://hl7.org/fhir");
|
||||
return !url.startsWith("http://hl7.org/fhir") && !type.equals("canonical");
|
||||
}
|
||||
|
||||
private boolean isMappingUri(String url) {
|
||||
if (mappingsUris.isEmpty()) {
|
||||
JsonObject json;
|
||||
try {
|
||||
json = JsonTrackingParser.fetchJson("http://hl7.org/fhir/mappingspaces.json");
|
||||
for (JsonObject ms : JSONUtil.objects(json, "spaces")) {
|
||||
mappingsUris.add(JSONUtil.str(ms, "url"));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// frozen R4 list
|
||||
mappingsUris.add("http://hl7.org/fhir/fivews");
|
||||
mappingsUris.add("http://hl7.org/fhir/workflow");
|
||||
mappingsUris.add("http://hl7.org/fhir/interface");
|
||||
mappingsUris.add("http://hl7.org/v2");
|
||||
mappingsUris.add("http://loinc.org");
|
||||
mappingsUris.add("http://snomed.org/attributebinding");
|
||||
mappingsUris.add("http://snomed.info/conceptdomain");
|
||||
mappingsUris.add("http://hl7.org/v3/cda");
|
||||
mappingsUris.add("http://hl7.org/v3");
|
||||
mappingsUris.add("http://nema.org/dicom");
|
||||
mappingsUris.add("http://w3.org/vcard");
|
||||
mappingsUris.add("http://ihe.net/xds");
|
||||
mappingsUris.add("http://www.w3.org/ns/prov");
|
||||
mappingsUris.add("http://ietf.org/rfc/2445");
|
||||
mappingsUris.add("http://www.omg.org/spec/ServD/1.0/");
|
||||
mappingsUris.add("http://metadata-standards.org/11179/");
|
||||
mappingsUris.add("http://ihe.net/data-element-exchange");
|
||||
mappingsUris.add("http://openehr.org");
|
||||
mappingsUris.add("http://siframework.org/ihe-sdc-profile");
|
||||
mappingsUris.add("http://siframework.org/cqf");
|
||||
mappingsUris.add("http://www.cdisc.org/define-xml");
|
||||
mappingsUris.add("http://www.cda-adc.ca/en/services/cdanet/");
|
||||
mappingsUris.add("http://www.pharmacists.ca/");
|
||||
mappingsUris.add("http://www.healthit.gov/quality-data-model");
|
||||
mappingsUris.add("http://hl7.org/orim");
|
||||
mappingsUris.add("http://hl7.org/fhir/w5");
|
||||
mappingsUris.add("http://hl7.org/fhir/logical");
|
||||
mappingsUris.add("http://hl7.org/fhir/auditevent");
|
||||
mappingsUris.add("http://hl7.org/fhir/provenance");
|
||||
mappingsUris.add("http://hl7.org/qidam");
|
||||
mappingsUris.add("http://cap.org/ecc");
|
||||
mappingsUris.add("http://fda.gov/UDI");
|
||||
mappingsUris.add("http://hl7.org/fhir/object-implementation");
|
||||
mappingsUris.add("http://github.com/MDMI/ReferentIndexContent");
|
||||
mappingsUris.add("http://ncpdp.org/SCRIPT10_6");
|
||||
mappingsUris.add("http://clinicaltrials.gov");
|
||||
mappingsUris.add("http://hl7.org/fhir/rr");
|
||||
mappingsUris.add("http://www.hl7.org/v3/PORX_RM020070UV");
|
||||
mappingsUris.add("https://bridgmodel.nci.nih.gov");
|
||||
mappingsUris.add("http://hl7.org/fhir/composition");
|
||||
mappingsUris.add("http://hl7.org/fhir/documentreference");
|
||||
mappingsUris.add("https://en.wikipedia.org/wiki/Identification_of_medicinal_products");
|
||||
mappingsUris.add("urn:iso:std:iso:11073:10201");
|
||||
mappingsUris.add("urn:iso:std:iso:11073:10207");
|
||||
}
|
||||
}
|
||||
return mappingsUris.contains(url);
|
||||
}
|
||||
|
||||
private String findBaseUrl(String url) {
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.hl7.fhir.validation.ValidationEngine.ValidationRecord;
|
||||
import org.hl7.fhir.validation.ValidationRecord;
|
||||
import org.hl7.fhir.validation.cli.model.*;
|
||||
import org.hl7.fhir.validation.cli.utils.EngineMode;
|
||||
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
|
||||
|
@ -81,8 +81,12 @@ public class ValidationService {
|
|||
if (r instanceof Bundle)
|
||||
for (Bundle.BundleEntryComponent e : ((Bundle) r).getEntry())
|
||||
ec = ec + displayOperationOutcome((OperationOutcome) e.getResource(), ((Bundle) r).getEntry().size() > 1) + ec;
|
||||
else
|
||||
else if (r == null) {
|
||||
ec = ec + 1;
|
||||
System.out.println("No output from validation - nothing to validate");
|
||||
} else {
|
||||
ec = displayOperationOutcome((OperationOutcome) r, false);
|
||||
}
|
||||
} else {
|
||||
IParser x;
|
||||
if (cliContext.getOutput() != null && cliContext.getOutput().endsWith(".json")) {
|
||||
|
|
|
@ -1969,7 +1969,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
} else {
|
||||
if (url.contains("hl7.org") || url.contains("fhir.org")) {
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE, url);
|
||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE, url);
|
||||
} else {
|
||||
warning(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE, url);
|
||||
}
|
||||
|
@ -2342,18 +2342,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
return null;
|
||||
} else {
|
||||
Set<Character> invalidChars = new HashSet<>();
|
||||
for (char ch : value.toCharArray()) {
|
||||
if (!(Character.isDigit(ch) || Character.isAlphabetic(ch) || Utilities.existsInList(ch, ';', '?', ':', '@', '&', '=', '+', '$', '.', ',', '/', '%', '-', '_', '~', '#', '[', ']', '!', '\'', '(', ')', '*' ))) {
|
||||
invalidChars.add(ch);
|
||||
Set<Character> invalidChars = new HashSet<>();
|
||||
for (char ch : value.toCharArray()) {
|
||||
if (!(Character.isDigit(ch) || Character.isAlphabetic(ch) || Utilities.existsInList(ch, ';', '?', ':', '@', '&', '=', '+', '$', '.', ',', '/', '%', '-', '_', '~', '#', '[', ']', '!', '\'', '(', ')', '*' ))) {
|
||||
invalidChars.add(ch);
|
||||
}
|
||||
}
|
||||
if (invalidChars.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return context.formatMessage(I18nConstants.XHTML_URL_INVALID_CHARS, invalidChars.toString());
|
||||
}
|
||||
}
|
||||
if (invalidChars.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return context.formatMessage(I18nConstants.XHTML_URL_INVALID_CHARS, invalidChars.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String checkValidMimeType(String mt) {
|
||||
|
|
|
@ -42,12 +42,18 @@ public class CodeSystemValidator extends BaseValidator {
|
|||
vs = null;
|
||||
}
|
||||
if (vs != null) {
|
||||
if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.hasCompose() && !vs.hasExpansion(), I18nConstants.CODESYSTEM_CS_VS_MISMATCH, url, vsu))
|
||||
if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getCompose().getInclude().size() == 1, I18nConstants.CODESYSTEM_CS_VS_INVALID, url, vsu))
|
||||
if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.hasCompose(), I18nConstants.CODESYSTEM_CS_VS_INVALID, url, vsu)) {
|
||||
if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getCompose().getInclude().size() == 1, I18nConstants.CODESYSTEM_CS_VS_INVALID, url, vsu)) {
|
||||
if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getCompose().getInclude().get(0).getSystem().equals(url), I18nConstants.CODESYSTEM_CS_VS_WRONGSYSTEM, url, vsu, vs.getCompose().getInclude().get(0).getSystem())) {
|
||||
rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !vs.getCompose().getInclude().get(0).hasValueSet()
|
||||
&& !vs.getCompose().getInclude().get(0).hasConcept() && !vs.getCompose().getInclude().get(0).hasFilter(), I18nConstants.CODESYSTEM_CS_VS_INCLUDEDETAILS, url, vsu);
|
||||
if (vs.hasExpansion()) {
|
||||
int count = countConcepts(cs);
|
||||
rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getExpansion().getContains().size() == count, I18nConstants.CODESYSTEM_CS_VS_EXP_MISMATCH, url, vsu, count, vs.getExpansion().getContains().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // todo... try getting the value set the other way...
|
||||
|
||||
|
@ -77,5 +83,14 @@ public class CodeSystemValidator extends BaseValidator {
|
|||
|
||||
}
|
||||
|
||||
private int countConcepts(Element cs) {
|
||||
List<Element> concepts = cs.getChildrenByName("concept");
|
||||
int res = concepts.size();
|
||||
for (Element concept : concepts) {
|
||||
res = res + countConcepts(concept);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -4,7 +4,9 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.convertors.VersionConvertor_10_50;
|
||||
import org.hl7.fhir.convertors.VersionConvertor_14_50;
|
||||
|
@ -19,12 +21,15 @@ import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
|||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ExpressionNode;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
@ -115,10 +120,12 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
private void validateElementDefinition(List<ValidationMessage> errors, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd) {
|
||||
boolean typeMustSupport = false;
|
||||
List<Element> types = element.getChildrenByName("type");
|
||||
Set<String> typeCodes = new HashSet<>();
|
||||
for (Element type : types) {
|
||||
if (hasMustSupportExtension(type)) {
|
||||
typeMustSupport = true;
|
||||
}
|
||||
typeCodes.add(type.getChildValue("code"));
|
||||
// check the stated profile - must be a constraint on the type
|
||||
if (snapshot || sd != null) {
|
||||
validateElementType(errors, type, stack.push(type, -1, null, null), sd, element.getChildValue("path"));
|
||||
|
@ -131,6 +138,50 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
hint(errors, IssueType.EXCEPTION, stack.getLiteralPath(), hasSnapshot || "true".equals(element.getChildValue("mustSupport")), I18nConstants.SD_NESTED_MUST_SUPPORT_DIFF, element.getNamedChildValue("path"));
|
||||
}
|
||||
}
|
||||
if (element.hasChild("binding")) {
|
||||
Element binding = element.getNamedChild("binding");
|
||||
validateBinding(errors, binding, stack.push(binding, -1, null, null), typeCodes, snapshot, element.getNamedChildValue("path"));
|
||||
} else {
|
||||
// this is a good idea but there's plenty of cases where the rule isn't met; maybe one day it's worth investing the time to exclude these cases and bring this rule back
|
||||
// String bt = boundType(typeCodes);
|
||||
// hint(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot || bt == null, I18nConstants.SD_ED_SHOULD_BIND, element.getNamedChildValue("path"), bt);
|
||||
}
|
||||
}
|
||||
|
||||
private String boundType(Set<String> typeCodes) {
|
||||
for (String tc : typeCodes) {
|
||||
if (Utilities.existsInList(tc, "code", "Coding", "CodeableConcept", "Quantity", "CodeableReference")) {
|
||||
return tc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String bindableType(Set<String> typeCodes) {
|
||||
String ret = boundType(typeCodes);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
for (String tc : typeCodes) {
|
||||
if (Utilities.existsInList(tc, "string", "uri", "CodeableConcept", "Quantity", "CodeableReference")) {
|
||||
return tc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void validateBinding(List<ValidationMessage> errors, Element binding, NodeStack stack, Set<String> typeCodes, boolean snapshot, String path) {
|
||||
rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot || bindableType(typeCodes) != null, I18nConstants.SD_ED_BIND_NO_BINDABLE, path, typeCodes.toString());
|
||||
if (binding.hasChild("valueSet")) {
|
||||
Element valueSet = binding.getNamedChild("valueSet");
|
||||
String ref = valueSet.hasPrimitiveValue() ? valueSet.primitiveValue() : valueSet.getNamedChildValue("reference");
|
||||
if (warning(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot || ref != null, I18nConstants.SD_ED_SHOULD_BIND_WITH_VS, path)) {
|
||||
Resource vs = context.fetchResource(Resource.class, ref);
|
||||
if (warning(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs != null, I18nConstants.SD_ED_BIND_UNKNOWN_VS, path, ref)) {
|
||||
rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs instanceof ValueSet, I18nConstants.SD_ED_BIND_NOT_VS, path, ref, vs.fhirType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateElementType(List<ValidationMessage> errors, Element type, NodeStack stack, StructureDefinition sd, String path) {
|
||||
|
@ -223,7 +274,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
if (t == null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), 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);
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd.getKind() == StructureDefinitionKind.RESOURCE, I18nConstants.SD_ED_TYPE_PROFILE_WRONG_TARGET, p, t, code, path, "Resource");
|
||||
}
|
||||
}
|
||||
} else if (code.equals("canonical")) {
|
||||
|
@ -231,9 +282,11 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
String t = determineBaseType(sd);
|
||||
if (t == null) {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), 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) || "Resource".equals(t), 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), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
|
||||
}
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(t), I18nConstants.SD_ED_TYPE_PROFILE_WRONG_TARGET, p, t, code, path, "Canonical Resource");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_NO_TARGET_PROFILE, code);
|
||||
|
@ -247,10 +300,11 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
return true;
|
||||
}
|
||||
sd = sd.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sd.getBaseDefinition()) : null;
|
||||
if (sd != null && !sd.getAbstract()) {
|
||||
if (!(VersionUtilities.isR2Ver(context.getVersion()) || VersionUtilities.isR2BVer(context.getVersion())) && sd != null && !sd.getAbstract()) {
|
||||
sd = null;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hl7.fhir.r5.model.Resource;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureMap;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||
|
@ -89,7 +90,7 @@ public class FHIRMappingLanguageTests {
|
|||
|
||||
String msg = null;
|
||||
try {
|
||||
StructureMap r = new org.hl7.fhir.r5.utils.StructureMapUtilities(context).parse(stringMap, map);
|
||||
StructureMap r = new StructureMapUtilities(context).parse(stringMap, map);
|
||||
context.cacheResource(r);
|
||||
org.hl7.fhir.r5.elementmodel.Element element = validationEngine.transform(byteSource, FhirFormat.JSON, r.getUrl());
|
||||
s = new ByteArrayOutputStream();
|
||||
|
|
|
@ -490,7 +490,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException {
|
||||
public boolean resolveURL(Object appContext, String path, String url, String type) throws IOException, FHIRException {
|
||||
return !url.contains("example.org") && !url.startsWith("http://hl7.org/fhir/invalid");
|
||||
}
|
||||
|
||||
|
|
10
pom.xml
10
pom.xml
|
@ -271,9 +271,13 @@
|
|||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
<_nouses>true</_nouses>
|
||||
<_removeheaders>Built-By, Include-Resource, Private-Package, Require-Capability</_removeheaders>
|
||||
<!-- No need to disable normal OSGi class loading
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
-->
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
Loading…
Reference in New Issue