Added IMPORT for all SDs, enabled batch SD ShEx Generation. Disabled Context translation temporarily

This commit is contained in:
dksharma 2023-02-23 23:19:13 -06:00
parent 5728cf94c2
commit 9ca531ff0a
3 changed files with 270 additions and 147 deletions

View File

@ -32,6 +32,8 @@ package org.hl7.fhir.r5.conformance;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
@ -63,9 +65,10 @@ public class ShExGenerator {
public ConstraintTranslationPolicy constraintPolicy = ConstraintTranslationPolicy.ALL;
private static String SHEX_TEMPLATE = "$header$\n\n" +
"$shapeDefinitions$";
private static String SHEX_TEMPLATE =
"$header$\n" +
"$imports$\n" +
"$shapeDefinitions$";
// A header is a list of prefixes, a base declaration and a start node
private static String FHIR = "http://hl7.org/fhir/";
@ -75,7 +78,9 @@ public class ShExGenerator {
"PREFIX fhirvs: <$fhirvs$>\n" +
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \n" +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n" +
"BASE <http://hl7.org/fhir/shape/>\n$start$";
"BASE <http://hl7.org/fhir/shape/>\n";
private static String IMPORT_TEMPLATE = "IMPORT <$import$$fileExt$>\n";
// Start template for single (open) entry
private static String START_TEMPLATE = "\n\nstart=@<$id$> AND {fhir:nodeRole [fhir:treeRoot]}\n";
@ -257,6 +262,8 @@ public class ShExGenerator {
// Extensions are Structure Definitions with type as "Extension".
private List<StructureDefinition> selectedExtensions;
private List<String> selectedExtensionUrls;
private List<String> imports;
private FHIRPathEngine fpe;
public ShExGenerator(IWorkerContext context) {
@ -276,6 +283,7 @@ public class ShExGenerator {
excludedSDUrls = new ArrayList<String>();
selectedExtensions = new ArrayList<StructureDefinition>();
selectedExtensionUrls = new ArrayList<String>();
imports = new ArrayList<String>();
fpe = new FHIRPathEngine(context);
}
@ -293,6 +301,7 @@ public class ShExGenerator {
references.clear();
required_value_sets.clear();
known_resources.clear();
imports.clear();
return generate(links, list);
}
@ -369,7 +378,6 @@ public class ShExGenerator {
shex_def.add("header",
tmplt(HEADER_TEMPLATE).
add("start", start_cmd).
add("fhir", FHIR).
add("fhirvs", FHIR_VS).render());
@ -380,6 +388,7 @@ public class ShExGenerator {
// We remove them. Also, it is possible for the same sd to have multiple hashes...
uniq_structures = new LinkedList<StructureDefinition>();
uniq_structure_urls = new HashSet<String>();
StringBuffer allStructures = new StringBuffer("");
for (StructureDefinition sd : structures) {
// Exclusion Criteria...
if ((excludedSDUrls != null) &&
@ -415,79 +424,89 @@ public class ShExGenerator {
}
}
boolean isShapeDefinitionEmpty = true;
for (StructureDefinition sd : uniq_structures) {
printBuildMessage(" ---- Generating ShEx for : " + sd.getName() + " [ " + sd.getUrl() + " ] ...");
String shapeDefinitionStr = genShapeDefinition(sd, true);
if (!shapeDefinitionStr.isEmpty()) {
isShapeDefinitionEmpty = false;
shapeDefinitions.append(shapeDefinitionStr);
} else {
printBuildMessage(" ---- WARNING! EMPTY/No ShEx SCHEMA Body generated for : " + sd.getName() + " [ " + sd.getUrl() + " ].\n" +
"This might not be an issue, if this resource is normative base or a meta resource");
shapeDefinitions.append("<" + sd.getName() + "> CLOSED {\n}");
}
else {
printBuildMessage(" ---- EMPTY/No ShEx SCHEMA generated for : " + sd.getName() + " [ " + sd.getUrl() + " ].");
if (!imports.isEmpty())
imports.removeIf(s -> s.contains(sd.getName()));
}
shapeDefinitions.append(emitInnerTypes());
// If data types are to be put in the same file
if (doDatatypes) {
shapeDefinitions.append("\n#---------------------- Data Types -------------------\n");
while (emittedDatatypes.size() < datatypes.size() ||
emittedInnerTypes.size() < innerTypes.size()) {
shapeDefinitions.append(emitDataTypes());
// As process data types, it may introduce some more inner types, so we repeat the call here.
shapeDefinitions.append(emitInnerTypes());
}
}
}
// There was not shape generated. return empty.
// No need to generate data types, references and valuesets
if (isShapeDefinitionEmpty) {
return "";
}
shapeDefinitions.append(emitInnerTypes());
// If data types are to be put in the same file
if(doDatatypes) {
shapeDefinitions.append("\n#---------------------- Data Types -------------------\n");
while (emittedDatatypes.size() < datatypes.size() ||
emittedInnerTypes.size() < innerTypes.size()) {
shapeDefinitions.append(emitDataTypes());
// As process data types, it may introduce some more inner types, so we repeat the call here.
shapeDefinitions.append(emitInnerTypes());
if (oneOrMoreTypes.size() > 0) {
shapeDefinitions.append("\n#---------------------- Cardinality Types (OneOrMore) -------------------\n");
oneOrMoreTypes.forEach((String oomType) -> {
shapeDefinitions.append(getOneOrMoreType(oomType));
});
}
}
if (oneOrMoreTypes.size() > 0) {
shapeDefinitions.append("\n#---------------------- Cardinality Types (OneOrMore) -------------------\n");
oneOrMoreTypes.forEach((String oomType) -> {
shapeDefinitions.append(getOneOrMoreType(oomType));
if (references.size() > 0) {
shapeDefinitions.append("\n#---------------------- Reference Types -------------------\n");
for (String r : references) {
shapeDefinitions.append("\n").append(tmplt(TYPED_REFERENCE_TEMPLATE).add("refType", r).render()).append("\n");
if (!"Resource".equals(r) && !known_resources.contains(r))
shapeDefinitions.append("\n").append(tmplt(TARGET_REFERENCE_TEMPLATE).add("refType", r).render()).append("\n");
}
}
if (completeModel && known_resources.size() > 0) {
shapeDefinitions.append("\n").append(tmplt(COMPLETE_RESOURCE_TEMPLATE)
.add("resources", StringUtils.join(known_resources, "> OR\n\t@<")).render());
List<String> all_entries = new ArrayList<String>();
for (String kr : known_resources)
all_entries.add(tmplt(ALL_ENTRY_TEMPLATE).add("id", kr).render());
shapeDefinitions.append("\n").append(tmplt(ALL_TEMPLATE)
.add("all_entries", StringUtils.join(all_entries, " OR\n\t")).render());
}
if (required_value_sets.size() > 0) {
shapeDefinitions.append("\n#---------------------- Value Sets ------------------------\n");
for (ValueSet vs : required_value_sets)
shapeDefinitions.append("\n").append(genValueSet(vs));
}
if ((unMappedFunctions != null) && (!unMappedFunctions.isEmpty())) {
debug("------------------------- Unmapped Functions ---------------------");
for (String um : unMappedFunctions) {
debug(um);
}
}
allStructures.append(shapeDefinitions + "\n");
StringBuffer allImports = new StringBuffer("");
if (!imports.isEmpty()) {
imports.sort(Comparator.comparingInt(String::length));
imports.forEach((String imp) -> {
ST import_def = tmplt(IMPORT_TEMPLATE);
import_def.add("import", imp);
import_def.add("fileExt", ".shex");
allImports.append(import_def.render());
});
}
if (references.size() > 0) {
shapeDefinitions.append("\n#---------------------- Reference Types -------------------\n");
for (String r : references) {
shapeDefinitions.append("\n").append(tmplt(TYPED_REFERENCE_TEMPLATE).add("refType", r).render()).append("\n");
if (!"Resource".equals(r) && !known_resources.contains(r))
shapeDefinitions.append("\n").append(tmplt(TARGET_REFERENCE_TEMPLATE).add("refType", r).render()).append("\n");
}
}
shex_def.add("shapeDefinitions", shapeDefinitions);
if(completeModel && known_resources.size() > 0) {
shapeDefinitions.append("\n").append(tmplt(COMPLETE_RESOURCE_TEMPLATE)
.add("resources", StringUtils.join(known_resources, "> OR\n\t@<")).render());
List<String> all_entries = new ArrayList<String>();
for(String kr: known_resources)
all_entries.add(tmplt(ALL_ENTRY_TEMPLATE).add("id", kr).render());
shapeDefinitions.append("\n").append(tmplt(ALL_TEMPLATE)
.add("all_entries", StringUtils.join(all_entries, " OR\n\t")).render());
}
if (required_value_sets.size() > 0) {
shapeDefinitions.append("\n#---------------------- Value Sets ------------------------\n");
for (ValueSet vs : required_value_sets)
shapeDefinitions.append("\n").append(genValueSet(vs));
}
if ((unMappedFunctions != null)&&(!unMappedFunctions.isEmpty())) {
debug("------------------------- Unmapped Functions ---------------------");
for (String um : unMappedFunctions) {
debug(um);
}
}
allImports.append(start_cmd);
shex_def.add("imports", allImports);
shex_def.add("shapeDefinitions", allStructures.toString());
return shex_def.render();
}
@ -502,7 +521,7 @@ public class ShExGenerator {
bd = sd.getBaseDefinition();
String[] els = bd.split("/");
bd = els[els.length - 1];
addImport("<" + bd + ">");
sId += "> EXTENDS @<" + bd;
}
@ -514,6 +533,7 @@ public class ShExGenerator {
return "";
String bd = (ed.getType().size() > 0)? (ed.getType().get(0).getCode()) : "";
if (bd != null && !bd.isEmpty() && !baseDataTypes.contains(bd)) {
addImport("<" + bd + ">");
bd = "> EXTENDS @<" + bd;
}
return bd;
@ -661,14 +681,14 @@ public class ShExGenerator {
String[] backRefs = toStore.split("\\.");
toStore = "a [fhir:" + backRefs[0] + "]";
for (int i = 1; i < backRefs.length; i++)
toStore = "( ^fhir:" + backRefs[i] + " {" + toStore + "} )";
toStore = "^fhir:" + backRefs[i] + " {" + toStore + "}";
if (!contextOfUse.contains(toStore)) {
contextOfUse.add(toStore);
}
}
}
contextOfUseStr = "^fhir:extension { " + StringUtils.join(contextOfUse, " OR \n\t\t\t\t") + "\n\t\t}";
contextOfUseStr = "^fhir:extension { " + StringUtils.join(contextOfUse, " OR \n ") + "\n }";
}
shape_defn.add("contextOfUse", contextOfUseStr);
@ -684,7 +704,7 @@ public class ShExGenerator {
private String translateConstraint(StructureDefinition sd, ElementDefinition ed, ElementDefinition.ElementDefinitionConstraintComponent constraint){
String translated = "";
if (constraint != null) {
if (false) {
String ce = constraint.getExpression();
String constItem = "FHIR-SD-Path:" + ed.getPath() + " Expression: " + ce;
try {
@ -700,11 +720,9 @@ public class ShExGenerator {
debug(" TRANSLATED\t"+ed.getPath()+"\t"+constraint.getHuman()+"\t"+constraint.getExpression()+"\t"+shexConstraint);
} catch (Exception e) {
String message = " FAILED to parse the constraint: " + constItem + " [ " + e.getMessage() + " ]";
// Now make this a comment so that it does not fail when schema is resolved in validator
// TODO: This needs to be fixed
// TODO: it should be
// translated = message
//String message = " FAILED to parse the constraint from Structure Definition: " + constItem + " [ " + e.getMessage() + " ]";
String message = " FAILED to parse the constraint from Structure Definition: " + constItem;
e.printStackTrace();
translated = "";
debug(message);
@ -1320,12 +1338,31 @@ public class ShExGenerator {
}
element_def.add("defn", defn);
addImport(defn);
element_def.add("card", card);
addComment(element_def, ed);
return element_def.render();
}
private void addImport(String typeDefn) {
if ((typeDefn != null) && (!typeDefn.isEmpty())) {
// String importType = StringUtils.substringBetween(typeDefn, "<", ">");
// if ((importType.indexOf(ONE_OR_MORE_PREFIX) == -1) &&
// (!imports.contains(importType)))
// imports.add(importType);
// }
Pattern p = Pattern.compile("<([^\\s>/]+)");
Matcher m = p.matcher(typeDefn);
while (m.find()) {
String tag = m.group(1);
//System.out.println("FOUND IMPORT: " + tag);
if ((tag.indexOf(ONE_OR_MORE_PREFIX) == -1) &&
(!imports.contains(tag)))
imports.add(tag);
}
}
}
private List<ElementDefinition> getChildren(StructureDefinition derived, ElementDefinition element) {
List<ElementDefinition> elements = derived.getSnapshot().getElement();
int index = elements.indexOf(element) + 1;
@ -1573,7 +1610,9 @@ public class ShExGenerator {
// shex_choice_entry.add("id", "fhir:" + base+Character.toUpperCase(ext.charAt(0)) + ext.substring(1) + " ");
shex_choice_entry.add("id", "");
shex_choice_entry.add("card", "");
shex_choice_entry.add("defn", genTypeRef(sd, ed, id, typ));
String typeDefn = genTypeRef(sd, ed, id, typ);
shex_choice_entry.add("defn", typeDefn);
addImport(typeDefn);
shex_choice_entry.add("comment", " ");
return shex_choice_entry.render();
}
@ -1604,6 +1643,8 @@ public class ShExGenerator {
one_or_more_type.add("oomType", oomType);
one_or_more_type.add("origType", origType);
one_or_more_type.add("restriction", restriction);
addImport(origType);
addImport(restriction);
one_or_more_type.add("comment", "");
return one_or_more_type.render();
}

View File

@ -20,21 +20,23 @@ public class ShexGeneratorTestUtils {
public String name;
public String url;
public String info;
public RESOURCE_CATEGORY kind;
public resDef(String _name, String _url, String _info){
public resDef(String _name, String _url, String _info, RESOURCE_CATEGORY _kind){
this.name = _name;
this.url = _url;
this.info = _info;
this.kind = _kind;
}
@Override
public String toString() {
return " " + name + "[ " + url + " ] ";
return " " + name + " (Kind: " + kind + " ) [ " + url + " ]";
}
}
public enum RESOURCE_CATEGORY{
LOGICAL_NAMES, STRUCTURE_DEFINITIONS, EXTENSIONS, PROFILES, ALL
LOGICAL_NAME, STRUCTURE_DEFINITION, EXTENSION, PROFILE, ALL, META_OR_EXAMPLE_OR_OTHER_IGNORE
}
/**
@ -48,26 +50,25 @@ public class ShexGeneratorTestUtils {
List<resDef> selSDs = new ArrayList<resDef>();
sds.forEach((StructureDefinition sd) -> {
switch(cat) {
case STRUCTURE_DEFINITIONS:
if (sd.getType().trim().equals(sd.getName().trim()))
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd)));
case STRUCTURE_DEFINITION:
if (getCategory(sd).equals(RESOURCE_CATEGORY.STRUCTURE_DEFINITION))
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd), RESOURCE_CATEGORY.STRUCTURE_DEFINITION));
break;
case LOGICAL_NAMES:
if (sd.getBaseDefinition() == null)
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd)));
case LOGICAL_NAME:
if (getCategory(sd).equals(RESOURCE_CATEGORY.LOGICAL_NAME))
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd), RESOURCE_CATEGORY.LOGICAL_NAME));
break;
case EXTENSIONS:
if ("Extension".equals(sd.getType()))
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd)));
case EXTENSION:
if (getCategory(sd).equals(RESOURCE_CATEGORY.EXTENSION))
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd), RESOURCE_CATEGORY.EXTENSION));
break;
case PROFILES:
if (!((sd.getBaseDefinition() == null) ||
("Extension".equals(sd.getType())) ||
(sd.getType().trim().equals(sd.getName().trim()))))
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd)));
case PROFILE:
if (getCategory(sd).equals(RESOURCE_CATEGORY.PROFILE))
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd), RESOURCE_CATEGORY.PROFILE));
break;
default:
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd)));
selSDs.add(new resDef(sd.getName(), sd.getUrl(), getSDInfo(sd), getCategory(sd)));
}
});
@ -81,6 +82,24 @@ public class ShexGeneratorTestUtils {
return selSDs;
}
private RESOURCE_CATEGORY getCategory(StructureDefinition sd) {
if ("Extension".equals(sd.getType()))
return RESOURCE_CATEGORY.EXTENSION;
if (sd.getBaseDefinition() == null)
return RESOURCE_CATEGORY.LOGICAL_NAME;
if (sd.getType().trim().equals(sd.getName().trim()))
return RESOURCE_CATEGORY.STRUCTURE_DEFINITION;
if (!((sd.getBaseDefinition() == null) ||
("Extension".equals(sd.getType())) ||
(sd.getType().trim().equals(sd.getName().trim()))))
return RESOURCE_CATEGORY.PROFILE;
return RESOURCE_CATEGORY.META_OR_EXAMPLE_OR_OTHER_IGNORE;
}
/**
* This method is used in testing only - during Resource Constraint translation to ShEx constructs.
* It can be used by future developers to avoid unnecessary processing of constraints
@ -196,7 +215,7 @@ public class ShexGeneratorTestUtils {
System.out.println("Printing " + title);
System.out.println("************************************************************************");
items.forEach((resDef item) -> {
System.out.println(item.name + " [" + item.url + "]");
System.out.println(item.name + " \t[" + item.url + "]\t" + item.info);
});
}
}

View File

@ -10,7 +10,6 @@ import java.util.List;
import es.weso.shex.Schema;
import es.weso.shex.validator.ShExsValidator;
import es.weso.shex.validator.ShExsValidatorBuilder;
import org.apache.commons.lang3.StringUtils;
import org.fhir.ucum.UcumException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
@ -36,92 +35,92 @@ public class ShexGeneratorTests {
public static void setup() {
}
private void doTest(String name) throws FileNotFoundException, IOException, FHIRException, UcumException {
StructureDefinition sd = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
if (sd == null) {
throw new FHIRException("StructuredDefinition for " + name + "was null");
}
Path outPath = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"), name.toLowerCase() + ".shex");
TextFile.stringToFile(new ShExGenerator(TestingUtilities.getSharedWorkerContext()).generate(HTMLLinkPolicy.NONE, sd), outPath.toString());
private void doTest(String name, ShexGeneratorTestUtils.RESOURCE_CATEGORY cat) throws FileNotFoundException, IOException, FHIRException, UcumException {
// StructureDefinition sd = TestingUtilities.getSharedWorkerContext().fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
// if (sd == null) {
// throw new FHIRException("StructuredDefinition for " + name + "was null");
// }
// Path outPath = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"), name.toLowerCase() + ".shex");
// TextFile.stringToFile(new ShExGenerator(TestingUtilities.getSharedWorkerContext()).generate(HTMLLinkPolicy.NONE, sd), outPath.toString());
// For Testing Schema Processing and Constraint Mapping related Development
// If you un-comment the following lines, please comment all other lines in this method.
//this.doTestThis(name.toLowerCase(), name, false, ShExGenerator.ConstraintTranslationPolicy.ALL, true, true);
this.doTestSingleSD(name.toLowerCase(), cat, name, false, ShExGenerator.ConstraintTranslationPolicy.ALL, true, true, false);
}
@Test
public void testId() throws FHIRException, IOException, UcumException {
doTest("id");
doTest("id", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testUri() throws FHIRException, IOException, UcumException {
doTest("uri");
doTest("uri", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testObservation() throws FHIRException, IOException, UcumException {
doTest("Observation");
doTest("Observation", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testRef() throws FHIRException, IOException, UcumException {
doTest("Reference");
doTest("Reference", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testAccount() throws FHIRException, IOException, UcumException {
doTest("Account");
doTest("Account", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testAppointment() throws FHIRException, IOException, UcumException {
doTest("Appointment");
doTest("Appointment", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testBundle() throws FHIRException, IOException, UcumException {
doTest("Bundle");
doTest("Bundle", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testAge() throws FHIRException, IOException, UcumException {
doTest("Age");
doTest("Age", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testMedicationRequest() throws FHIRException, IOException, UcumException {
doTest("MedicationRequest");
doTest("MedicationRequest", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testAllergyIntolerance() throws FHIRException, IOException, UcumException {
doTest("AllergyIntolerance");
doTest("AllergyIntolerance", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testCoding() throws FHIRException, IOException, UcumException {
doTest("Coding");
doTest("Coding", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testTiming() throws FHIRException, IOException, UcumException {
doTest("Timing");
doTest("Timing", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Test
public void testSignature() throws FHIRException, IOException, UcumException {
doTest("Signature");
doTest("Signature", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
@Ignore
public void testCapabilityStatement() throws FHIRException, IOException, UcumException {
doTest("CapabilityStatement");
doTest("CapabilityStatement", ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION);
}
private void doTestThis(String shortName, String name, boolean useSelectedExtensions, ShExGenerator.ConstraintTranslationPolicy policy, boolean debugMode, boolean validateShEx) {
private void doTestSingleSD(String shortName, ShexGeneratorTestUtils.RESOURCE_CATEGORY cat, String name, boolean useSelectedExtensions, ShExGenerator.ConstraintTranslationPolicy policy, boolean debugMode, boolean validateShEx, boolean excludeMetaSDs) {
IWorkerContext ctx = TestingUtilities.getSharedWorkerContext();
StructureDefinition sd = ctx.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
if (sd == null) {
throw new FHIRException("StructuredDefinition for " + name + " was null");
throw new FHIRException("StructuredDefinition for " + name + "(Kind:" + cat + ") was null");
}
//Path outPath = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"), name.toLowerCase() + ".shex");
Path outPath = FileSystems.getDefault().getPath(System.getProperty("user.home") + "/runtime_environments/ShExSchemas", shortName + ".shex");
@ -131,9 +130,11 @@ public class ShexGeneratorTests {
this.shexGenerator.debugMode = debugMode;
this.shexGenerator.constraintPolicy = policy;
// ShEx Generator skips resources which are at Meta level of FHIR Resource definitions
this.shexGenerator.setExcludedStructureDefinitionUrls(
ShexGeneratorTestUtils.getMetaStructureDefinitionsToSkip());
if (excludeMetaSDs) {
// ShEx Generator skips resources which are at Meta level of FHIR Resource definitions
this.shexGenerator.setExcludedStructureDefinitionUrls(
ShexGeneratorTestUtils.getMetaStructureDefinitionsToSkip());
}
// when ShEx translates only selected resource extensions
if (useSelectedExtensions) {
@ -155,10 +156,10 @@ public class ShexGeneratorTests {
Schema sch = validator.schema();
Assert.assertNotNull(sch);
System.out.println("VALIDATION PASSED for ShEx Schema " + sd.getName());
System.out.println("VALIDATION PASSED for ShEx Schema " + sd.getName() + " (Kind:" + cat + ")" );
} catch (Exception e) {
System.out.println("VALIDATION FAILED for ShEx Schema " + sd.getName());
//System.out.println("\t\t\tMessage: " + e.getMessage());
System.out.println("VALIDATION FAILED for ShEx Schema " + sd.getName() + " (Kind:" + cat + ")" );
e.printStackTrace();
}
}
TextFile.stringToFile(schema, outPath.toString());
@ -168,7 +169,55 @@ public class ShexGeneratorTests {
}
}
@Ignore
private void doTestBatchSD(List<StructureDefinition> sds, boolean useSelectedExtensions, ShExGenerator.ConstraintTranslationPolicy policy, boolean debugMode, boolean validateShEx, boolean excludeMetaSDs) {
IWorkerContext ctx = TestingUtilities.getSharedWorkerContext();
//Path outPath = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"), name.toLowerCase() + ".shex");
Path outPath = FileSystems.getDefault().getPath(System.getProperty("user.home") + "/runtime_environments/ShExSchemas", "ShEx.shex");
try {
this.shexGenerator = new ShExGenerator(ctx);
this.shexGenerator.debugMode = debugMode;
this.shexGenerator.constraintPolicy = policy;
if (excludeMetaSDs) {
// ShEx Generator skips resources which are at Meta level of FHIR Resource definitions
this.shexGenerator.setExcludedStructureDefinitionUrls(
ShexGeneratorTestUtils.getMetaStructureDefinitionsToSkip());
}
// when ShEx translates only selected resource extensions
if (useSelectedExtensions) {
List<StructureDefinition> selExtns = new ArrayList<StructureDefinition>();
for (String eUrl : ShexGeneratorTestUtils.getSelectedExtensions()) {
StructureDefinition esd = ctx.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(eUrl, null));
if (esd != null)
selExtns.add(esd);
}
this.shexGenerator.setSelectedExtension(selExtns);
}
String schema = this.shexGenerator.generate(HTMLLinkPolicy.NONE, sds);
if (!schema.isEmpty()) {
if (validateShEx) {
try {
ShExsValidator validator = ShExsValidatorBuilder.fromStringSync(schema, "ShexC");
Schema sch = validator.schema();
Assert.assertNotNull(sch);
System.out.println("VALIDATION PASSED for ShEx Schema ALL SHEX STRUCTURES");
} catch (Exception e) {
System.out.println("VALIDATION FAILED for ShEx Schema ALL SHEX STRUCTURES");
e.printStackTrace();
}
}
TextFile.stringToFile(schema, outPath.toString());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void doTestAll() throws FileNotFoundException, IOException, FHIRException, UcumException {
List<StructureDefinition> sds = TestingUtilities.getSharedWorkerContext().fetchResourcesByType(StructureDefinition.class);
@ -176,8 +225,9 @@ public class ShexGeneratorTests {
ShexGeneratorTestUtils.RESOURCE_CATEGORY.ALL, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
false, //Process all extensions
ShExGenerator.ConstraintTranslationPolicy.ALL
ShExGenerator.ConstraintTranslationPolicy.ALL,
// Process all types of constraints, do not skip
true
);
}
@ -189,8 +239,9 @@ public class ShexGeneratorTests {
ShexGeneratorTestUtils.RESOURCE_CATEGORY.ALL, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
false, //Process all extensions
ShExGenerator.ConstraintTranslationPolicy.GENERIC_ONLY
ShExGenerator.ConstraintTranslationPolicy.GENERIC_ONLY,
// Process generic constraints only, ignore constraints of type 'context of use'
false
);
}
@ -203,8 +254,9 @@ public class ShexGeneratorTests {
ShexGeneratorTestUtils.RESOURCE_CATEGORY.ALL, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
false, //Process all extensions
ShExGenerator.ConstraintTranslationPolicy.CONTEXT_OF_USE_ONLY
ShExGenerator.ConstraintTranslationPolicy.CONTEXT_OF_USE_ONLY,
// Process constraints only where context of use found, skip otherwise
false
);
}
@ -216,7 +268,8 @@ public class ShexGeneratorTests {
ShexGeneratorTestUtils.RESOURCE_CATEGORY.ALL, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
true, //Process only given/selected extensions, ignore other extensions
ShExGenerator.ConstraintTranslationPolicy.ALL // Process all type of constraints
ShExGenerator.ConstraintTranslationPolicy.ALL, // Process all type of constraints
false
);
}
@ -225,10 +278,11 @@ public class ShexGeneratorTests {
List<StructureDefinition> sds = TestingUtilities.getSharedWorkerContext().fetchResourcesByType(StructureDefinition.class);
processSDList(
ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITIONS, // Processing All kinds of Structure Definitions
ShexGeneratorTestUtils.RESOURCE_CATEGORY.STRUCTURE_DEFINITION, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
false, //Process only given/selected extensions, ignore other extensions
ShExGenerator.ConstraintTranslationPolicy.ALL // Process all type of constraints
ShExGenerator.ConstraintTranslationPolicy.ALL, // Process all type of constraints
false
);
}
@ -237,10 +291,11 @@ public class ShexGeneratorTests {
List<StructureDefinition> sds = TestingUtilities.getSharedWorkerContext().fetchResourcesByType(StructureDefinition.class);
processSDList(
ShexGeneratorTestUtils.RESOURCE_CATEGORY.EXTENSIONS, // Processing All kinds of Structure Definitions
ShexGeneratorTestUtils.RESOURCE_CATEGORY.EXTENSION, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
false, //Process only given/selected extensions, ignore other extensions
ShExGenerator.ConstraintTranslationPolicy.ALL // Process all type of constraints
ShExGenerator.ConstraintTranslationPolicy.ALL, // Process all type of constraints
false
);
}
@ -249,10 +304,11 @@ public class ShexGeneratorTests {
List<StructureDefinition> sds = TestingUtilities.getSharedWorkerContext().fetchResourcesByType(StructureDefinition.class);
processSDList(
ShexGeneratorTestUtils.RESOURCE_CATEGORY.LOGICAL_NAMES, // Processing All kinds of Structure Definitions
ShexGeneratorTestUtils.RESOURCE_CATEGORY.LOGICAL_NAME, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
false, //Process only given/selected extensions, ignore other extensions
ShExGenerator.ConstraintTranslationPolicy.ALL // Process all type of constraints
ShExGenerator.ConstraintTranslationPolicy.ALL, // Process all type of constraints
false
);
}
@ -260,17 +316,19 @@ public class ShexGeneratorTests {
public void testProfilesOnly() throws FileNotFoundException, IOException, FHIRException, UcumException {
List<StructureDefinition> sds = TestingUtilities.getSharedWorkerContext().fetchResourcesByType(StructureDefinition.class);
processSDList(
ShexGeneratorTestUtils.RESOURCE_CATEGORY.PROFILES, // Processing All kinds of Structure Definitions
ShexGeneratorTestUtils.RESOURCE_CATEGORY.PROFILE, // Processing All kinds of Structure Definitions
sds, // List of Structure Definitions
false, //Process only given/selected extensions, ignore other extensions
ShExGenerator.ConstraintTranslationPolicy.ALL // Process all type of constraints
ShExGenerator.ConstraintTranslationPolicy.ALL, // Process all type of constraints
false
);
}
private void processSDList(ShexGeneratorTestUtils.RESOURCE_CATEGORY cat,
List<StructureDefinition> sds,
boolean useSelectedExtensions,
ShExGenerator.ConstraintTranslationPolicy policy) {
ShExGenerator.ConstraintTranslationPolicy policy,
boolean batchMode) {
if ((sds == null) || (sds.isEmpty())) {
throw new FHIRException("No StructuredDefinition found!");
}
@ -283,15 +341,20 @@ public class ShexGeneratorTests {
System.out.println("Processing " + cat);
System.out.println("************************************************************************");
sdDefs.forEach((ShexGeneratorTestUtils.resDef resDef) -> {
String name = resDef.url;
if (resDef.url.indexOf("/") != -1) {
String els[] = resDef.url.split("/");
name = els[els.length - 1];
}
System.out.println("******************** " + resDef + " *********************");
doTestThis(name, resDef.url, useSelectedExtensions, policy, true, true);
});
if (!batchMode) {
sdDefs.forEach((ShexGeneratorTestUtils.resDef resDef) -> {
String name = resDef.url;
if (resDef.url.indexOf("/") != -1) {
String els[] = resDef.url.split("/");
name = els[els.length - 1];
}
System.out.println("******************** " + resDef + " *********************");
doTestSingleSD(name, resDef.kind, resDef.url, useSelectedExtensions, policy, true, true, false);
});
} else {
doTestBatchSD(sds, useSelectedExtensions, policy, true, true, false);
}
System.out.println("************************ END PROCESSING ******************************");