Merge pull request #1168 from hapifhir/gg-202303-more_sm_never_ends

Gg 202303 more sm never ends
This commit is contained in:
Grahame Grieve 2023-03-13 14:32:53 +11:00 committed by GitHub
commit 00090230cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 208 additions and 5 deletions

View File

@ -112,6 +112,7 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
// and we only patch URLs to support version transforms
// so we just patch sd/od -> vs -> cs
protected void doPatchUrls(Resource resource) {
resource.setUserData("old.load.mode", true);
if (resource instanceof CanonicalResource) {
CanonicalResource cr = (CanonicalResource) resource;
cr.setUrl(patchUrl(cr.getUrl(), cr.fhirType()));

View File

@ -570,7 +570,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
public List<String> getResourceNames() {
Set<String> result = new HashSet<String>();
for (StructureDefinition sd : listStructures()) {
if (sd.getKind() == StructureDefinitionKind.RESOURCE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION)
if (sd.getKind() == StructureDefinitionKind.RESOURCE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && !sd.hasUserData("old.load.mode"))
result.add(sd.getName());
}
return Utilities.sorted(result);

View File

@ -61,6 +61,7 @@ import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext.FunctionDetails;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.MergedList;
import org.hl7.fhir.utilities.MergedList.MergeNode;
import org.hl7.fhir.utilities.SourceLocation;
@ -4173,6 +4174,10 @@ public class FHIRPathEngine {
result.add(new StringType(Utilities.escapeXml(cnt)));
} else if ("json".equals(param)) {
result.add(new StringType(Utilities.escapeJson(cnt)));
} else if ("url".equals(param)) {
result.add(new StringType(Utilities.URLEncode(cnt)));
} else if ("md".equals(param)) {
result.add(new StringType(MarkDownProcessor.makeStringSafeAsMarkdown(cnt)));
}
}
@ -4190,6 +4195,10 @@ public class FHIRPathEngine {
result.add(new StringType(Utilities.unescapeXml(cnt)));
} else if ("json".equals(param)) {
result.add(new StringType(Utilities.unescapeJson(cnt)));
} else if ("url".equals(param)) {
result.add(new StringType(Utilities.URLDecode(cnt)));
} else if ("md".equals(param)) {
result.add(new StringType(MarkDownProcessor.makeMarkdownForString(cnt)));
}
}
@ -4222,9 +4231,14 @@ public class FHIRPathEngine {
private List<Base> funcJoin(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
List<Base> nl = execute(context, focus, exp.getParameters().get(0), true);
String param = nl.get(0).primitiveValue();
String param2 = param;
if (exp.getParameters().size() == 2) {
nl = execute(context, focus, exp.getParameters().get(1), true);
param2 = nl.get(0).primitiveValue();
}
List<Base> result = new ArrayList<Base>();
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(param);
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(param, param2);
for (Base i : focus) {
b.append(i.primitiveValue());
}

View File

@ -658,6 +658,9 @@ public class StructureMapUtilities {
case "title" :
result.setTitle(lexer.readConstant("title"));
break;
case "status" :
result.setStatus(PublicationStatus.fromCode(lexer.readConstant("status")));
break;
default:
lexer.readConstant("nothing");
// nothing
@ -666,7 +669,7 @@ public class StructureMapUtilities {
}
if (!result.hasId() && result.hasName()) {
String id = Utilities.makeId(result.getName());
if (Utilities.noString(id)) {
if (!Utilities.noString(id)) {
result.setId(id);
}
}
@ -2697,4 +2700,65 @@ public class StructureMapUtilities {
this.exceptionsForChecks = exceptionsForChecks;
}
public List<StructureMap> getMapsForUrl(List<StructureMap> maps, String url, StructureMapInputMode mode) {
List<StructureMap> res = new ArrayList<>();
for (StructureMap map : maps) {
if (mapIsForUrl(map, url, mode)) {
res.add(map);
}
}
return res;
}
private boolean mapIsForUrl(StructureMap map, String url, StructureMapInputMode mode) {
for (StructureMapGroupComponent grp : map.getGroup()) {
if (grp.getTypeMode() != StructureMapGroupTypeMode.NULL) {
for (StructureMapGroupInputComponent p : grp.getInput()) {
if (mode == null || mode == p.getMode()) {
String t = resolveInputType(p, map);
if (url.equals(t)) {
return true;
}
}
}
}
}
return false;
}
public List<StructureMap> getMapsForUrlPrefix(List<StructureMap> maps, String url, StructureMapInputMode mode) {
List<StructureMap> res = new ArrayList<>();
for (StructureMap map : maps) {
if (mapIsForUrlPrefix(map, url, mode)) {
res.add(map);
}
}
return res;
}
private boolean mapIsForUrlPrefix(StructureMap map, String url, StructureMapInputMode mode) {
for (StructureMapGroupComponent grp : map.getGroup()) {
if (grp.getTypeMode() != StructureMapGroupTypeMode.NULL) {
for (StructureMapGroupInputComponent p : grp.getInput()) {
if (mode == null || mode == p.getMode()) {
String t = resolveInputType(p, map);
if (t != null && t.startsWith(url)) {
return true;
}
}
}
}
}
return false;
}
private String resolveInputType(StructureMapGroupInputComponent p, StructureMap map) {
for (StructureMapStructureComponent struc : map.getStructure()) {
if (struc.hasAlias() && struc.getAlias().equals(p.getType())) {
return struc.getUrl();
}
}
return null;
}
}

View File

@ -1980,6 +1980,20 @@ public class Utilities {
}
}
public static String tail(String url) {
int i = url.length()-1;
while (i >= 0 && isTokenChar(url.charAt(i))) {
i--;
}
if (i < 0) {
return url;
} else {
return url.substring(i+1);
}
}
//public static boolean !isWhitespace(String s) {
//boolean ok = true;
//for (int i = 0; i < s.length(); i++)

View File

@ -0,0 +1,110 @@
package org.hl7.fhir.validation.special;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureMap;
import org.hl7.fhir.r5.model.StructureMap.StructureMapInputMode;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext.SimpleWorkerContextBuilder;
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
import org.hl7.fhir.r5.utils.structuremap.VariableMode;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonException;
import org.hl7.fhir.utilities.json.model.JsonObject;
import org.hl7.fhir.utilities.json.model.JsonProperty;
import org.hl7.fhir.utilities.json.parser.JsonParser;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
public class R4R5MapTester {
private SimpleWorkerContext context;
private FilesystemPackageCacheManager pcm;
private StructureMapUtilities utils;
private List<StructureMap> allMaps;
public static void main(String[] args) throws JsonException, IOException {
// arg[0] is the location of the fhir-extensions repo
new R4R5MapTester().testMaps(args[0]);
}
private void testMaps(String src) throws JsonException, IOException {
log("Load Test Outcomes");
JsonObject json = JsonParser.parseObjectFromFile(Utilities.path(src, "input", "_data", "conversions.json"));
log("Load R5");
pcm = new FilesystemPackageCacheManager(true);
context = new SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).fromPackage(pcm.loadPackage("hl7.fhir.r5.core#current"));
log("Load Maps");
context.loadFromPackage(pcm.loadPackage("hl7.fhir.uv.extensions#dev"), null);
utils = new StructureMapUtilities(context);
allMaps = context.fetchResourcesByType(StructureMap.class);
log("Resource Count = "+context.getResourceNames().size());
log("Map Count = "+allMaps.size());
boolean changed = false;
for (JsonProperty jp : json.getProperties()) {
String rn = jp.getName();
log(" "+rn);
JsonObject o = json.getJsonObject(rn);
StructureDefinition sd = context.fetchTypeDefinition(rn);
List<StructureMap> mapSrc = utils.getMapsForUrl(allMaps, sd.getUrl(), StructureMapInputMode.SOURCE);
List<StructureMap> mapTgt = utils.getMapsForUrl(allMaps, sd.getUrl(), StructureMapInputMode.TARGET);
changed = checkMaps(rn, o.getJsonObject("r4"), "http://hl7.org/fhir/4.0", mapSrc, mapTgt) || changed;
changed = checkMaps(rn, o.getJsonObject("r4b"), "http://hl7.org/fhir/4.0", mapSrc, mapTgt) || changed;
}
if (changed) {
JsonParser.compose(json, new FileOutputStream(Utilities.path(src, "input", "_data", "conversions.json")), true);
}
// load R4
// load R4B
// load the maps
// load the existing outcomes
//
// for R4:
// fetch the examples package
// for each R5 resource type
// find the map
// get the source name
// iterate the examples
// find the applicable map
// do the conversion
// write outcome
}
private boolean checkMaps(String rn, JsonObject json, String ns, List<StructureMap> mapSrc, List<StructureMap> mapTgt) {
List<StructureMap> src = utils.getMapsForUrlPrefix(mapSrc, ns, StructureMapInputMode.TARGET);
List<StructureMap> tgt = utils.getMapsForUrlPrefix(mapTgt, ns, StructureMapInputMode.SOURCE);
if (src.size() + tgt.size() == 0) {
json.set("status", "No Maps Defined");
json.set("testColor", "#dddddd");
json.set("testMessage", "--");
} else {
boolean isDraft = false;
for (StructureMap map : src) {
isDraft = map.getStatus() == PublicationStatus.DRAFT || isDraft;
}
for (StructureMap map : tgt) {
isDraft = map.getStatus() == PublicationStatus.DRAFT || isDraft;
}
json.set("status", ""+(src.size()+tgt.size())+" Maps Defined"+(isDraft ? " (draft)" : ""));
if (context.getResourceNames().contains(rn)) {
json.set("testColor", "#ffcccc");
json.set("testMessage", "To Do");
} else {
json.set("testColor", "#eeeeee");
json.set("testMessage", "n/a");
}
}
return true;
}
private void log(String msg) {
System.out.println(msg);
}
}