This commit is contained in:
Grahame Grieve 2020-12-15 07:50:45 +11:00
commit 5b52a75d3b
26 changed files with 3694 additions and 3668 deletions

View File

@ -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

View File

@ -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.
*/

View File

@ -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;

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}
}

View File

@ -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;
}
}

View File

@ -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() + ")";
}
}

View File

@ -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();
}
}

View File

@ -0,0 +1,5 @@
package org.hl7.fhir.r5.utils.structuremap;
public enum VariableMode {
INPUT, OUTPUT, SHARED
}

View File

@ -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() + "]";
}
}

View File

@ -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() + "]";
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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;

View File

@ -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();