Skip to content

Commit

Permalink
Merge pull request #1866 from hapifhir/2024-12-gg-test-instance-gener…
Browse files Browse the repository at this point in the history
…ation-2

2024 12 gg test instance generation 2
  • Loading branch information
grahamegrieve authored Dec 24, 2024
2 parents e021fb3 + 7170545 commit 22eacf9
Show file tree
Hide file tree
Showing 54 changed files with 3,075 additions and 531 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.hl7.fhir.utilities.json.parser.JsonParser;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.NpmPackage.PackagedResourceFile;
import org.hl7.fhir.utilities.npm.PackageClient;
import org.hl7.fhir.utilities.npm.PackageInfo;
import org.hl7.fhir.utilities.npm.PackageServer;
Expand Down Expand Up @@ -357,6 +358,7 @@ private void processPackage(String pid, String v, int i, int t) throws IOExcepti
npm = pcm.loadPackage(pid, v);
} catch (Throwable e) {
System.out.println("Unable to load package: "+pid+"#"+v+": "+e.getMessage());
return;
}

try {
Expand All @@ -378,15 +380,13 @@ private void processPackage(String pid, String v, int i, int t) throws IOExcepti
if (ok) {
int c = 0;
if (fv != null && (versions.isEmpty() || versions.contains(fv))) {
for (String type : resourceTypes) {
for (String s : npm.listResources(type)) {
c++;
try {
processor.processResource(ctxt, context, type, s, TextFile.streamToBytes(npm.load("package", s)));
} catch (Exception e) {
System.out.println("####### Error loading "+pid+"#"+v +"["+fv+"]/"+type+" ####### "+e.getMessage());
e.printStackTrace();
}
for (PackagedResourceFile p : npm.listAllResources(resourceTypes)) {
c++;
try {
processor.processResource(ctxt, context, p.getResourceType(), p.getFilename(), TextFile.streamToBytes(npm.load(p.getFolder(), p.getFilename())));
} catch (Exception e) {
System.out.println("####### Error loading "+pid+"#"+v +"["+fv+"]/"+p.getResourceType()+" ####### "+e.getMessage());
e.printStackTrace();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@

import org.hl7.fhir.convertors.analytics.PackageVisitor.IPackageVisitorProcessor;
import org.hl7.fhir.convertors.analytics.PackageVisitor.PackageContext;
import org.hl7.fhir.convertors.loaders.loaderR5.ILoaderKnowledgeProviderR5;
import org.hl7.fhir.convertors.loaders.loaderR5.NullLoaderKnowledgeProviderR5;
import org.hl7.fhir.convertors.loaders.loaderR5.R2016MayToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R2ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R3ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R4BToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R4ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R5ToR5Loader;
import org.hl7.fhir.convertors.loaders.loaderR5.R6ToR5Loader;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IContextResourceLoader;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext.SimpleWorkerContextBuilder;
Expand All @@ -37,6 +47,7 @@
import org.hl7.fhir.utilities.http.ManagedWebAccess.WebAccessPolicy;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.NpmPackage.PackagedResourceFile;
import org.xml.sax.SAXException;

public class TestGenerationDataGenerator implements IPackageVisitorProcessor {
Expand Down Expand Up @@ -67,6 +78,7 @@ public void alreadyVisited(String pid) {

@Override
public Object startPackage(PackageContext ctxt) {
System.out.println("Process Package "+ctxt.getPid()+"#"+ctxt.getVersion()+" ("+ctxt.getNpm().fhirVersion()+")");
return null;
}

Expand All @@ -77,22 +89,45 @@ public void processResource(PackageContext ctxt, Object context, String type, St
if (worker == null) {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().build();
NpmPackage npm = pcm.loadPackage(VersionUtilities.packageForVersion(version));
SimpleWorkerContext swc = new SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).fromPackage(npm);
IContextResourceLoader loader = makeLoader(ctxt.getNpm().fhirVersion(), new NullLoaderKnowledgeProviderR5());
SimpleWorkerContext swc = new SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).fromPackage(npm, loader, true);
contexts.put(version, swc);
worker = swc;
}
List<ValidatedFragment> res = Manager.parse(worker, new ByteArrayInputStream(content), FhirFormat.JSON);
if (res.size() > 0) {
try {
processElement(res.get(0).getElement());
processElement(res.get(0).getElement(), null);
} catch (SQLException e) {
throw new FHIRException(e);
}
}
}

private void processElement(Element element) throws SQLException {
String id = element.getProperty().getDefinition().getId();
private IContextResourceLoader makeLoader(String version, ILoaderKnowledgeProviderR5 loader) {
if (VersionUtilities.isR2Ver(version)) {
return new R2ToR5Loader(Utilities.strings("Conformance", "StructureDefinition", "ValueSet", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"), loader);
}
if (VersionUtilities.isR2BVer(version)) {
return new R2016MayToR5Loader(Utilities.strings("Conformance", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"), loader); // special case
}
if (VersionUtilities.isR3Ver(version)) {
return new R3ToR5Loader(Utilities.strings("CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"), loader);
}
if (VersionUtilities.isR4Ver(version)) {
return new R4ToR5Loader(Utilities.strings("CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"), loader, version);
}
if (VersionUtilities.isR4BVer(version)) {
return new R4BToR5Loader(Utilities.strings("CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"), loader, version);
}
if (VersionUtilities.isR6Ver(version)) {
return new R6ToR5Loader(Utilities.strings("CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"), loader);
}
return new R5ToR5Loader(Utilities.strings("CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire", "ConceptMap", "StructureMap", "NamingSystem"), loader);
}

private void processElement(Element element, String path) throws SQLException {
String id = path != null ? path : element.getProperty().getDefinition().getId();
switch (element.fhirType()) {
case "Address":
recordValue(id, "Address", getValues(element, "use", "type", "text", "line", "city", "district", "state", "postalCode", "country"));
Expand Down Expand Up @@ -161,12 +196,23 @@ private void processElement(Element element) throws SQLException {
break;
default:
if (element.isPrimitive()) {
recordValue(id, element.fhirType(), element.primitiveValue());
if (!element.getProperty().getDefinition().getId().equals("Extension.url")) {
recordValue(id, element.fhirType(), element.primitiveValue());
}
} else {
for (Element child : element.getChildren()) {
if (!child.fhirType().equals("Extension") && !child.getPath().endsWith(".id") && !child.getPath().endsWith(".linkId")) {
if (child.fhirType().equals("Extension")) {
String url = child.getChildValue("url");
String npath;
if (Utilities.isAbsoluteUrl(url) || path == null) {
npath = url;
} else {
npath = path+"."+url;
}
processElement(child, npath);
} else if (!child.getPath().endsWith(".id") && !child.getPath().endsWith(".linkId")) {
if (!child.isResource() || !Utilities.existsInList(child.fhirType(), "Bundle", "CapabilityStatement", "CodeSystem", "ConceptMap", "GraphDefinition", "ImplementationGuide", "MessageHeader", "NamingSystem", "OperationDefinition", "OperationOutcome", "Parameters", "SearchParameter", "StructureDefinition", "StructureMap", "TerminologyCapabilities", "ValueSet")) {
processElement(child);
processElement(child, path);
}
}
}
Expand Down Expand Up @@ -325,9 +371,9 @@ private void processPackage(NpmPackage npm) throws IOException, FHIRException, E
for (String type : resourceTypes) {
List<String> rt = new ArrayList<String>();
rt.add(type);
for (StringPair s : npm.listAllResources(rt)) {
for (PackagedResourceFile s : npm.listAllResources(rt)) {
c++;
processResource(ctxt, context, type, s.getName(), TextFile.streamToBytes(npm.load(s.getName(), s.getValue())));
processResource(ctxt, context, type, s.getFilename(), TextFile.streamToBytes(npm.load(s.getFolder(), s.getFilename())));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public PEDefinition buildPEDefinition(StructureDefinition profile) {
if (!profile.hasSnapshot()) {
throw new DefinitionException("Profile '"+profile.getVersionedUrl()+"' does not have a snapshot");
}
return new PEDefinitionResource(this, profile, profile.getName());
return new PEDefinitionResource(this, profile, null);
}

/**
Expand Down Expand Up @@ -342,6 +342,7 @@ private StructureDefinition getProfile(String url, String version) {

protected List<PEDefinition> listChildren(boolean allFixed, PEDefinition parent, StructureDefinition profileStructure, ElementDefinition definition, String url, String... omitList) {
StructureDefinition profile = profileStructure;
boolean inExtension = profile.getDerivation() == TypeDerivationRule.CONSTRAINT && "Extension".equals(profile.getType());
List<ElementDefinition> list = pu.getChildList(profile, definition);
if (definition.getType().size() == 1 || (!definition.getPath().contains(".")) || list.isEmpty()) {
assert url == null || checkType(definition, url);
Expand All @@ -359,43 +360,38 @@ protected List<PEDefinition> listChildren(boolean allFixed, PEDefinition parent,
while (i < list.size()) {
ElementDefinition defn = list.get(i);
if (!defn.getMax().equals("0") && (allFixed || include(defn))) {
if (passElementPropsCheck(defn) && !Utilities.existsInList(defn.getName(), omitList)) {
if (defn.getType().size() > 1) {
// Debug/Utilities.breakpoint();
i++;
} else {
String name = uniquefy(names, defn.getName());
PEDefinitionElement pe = new PEDefinitionElement(this, name, profile, defn, parent.path());
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
pe.setMustHaveValue(definition.getMustHaveValue());
if (passElementPropsCheck(defn, inExtension) && !Utilities.existsInList(defn.getName(), omitList)) {
String name = uniquefy(names, defn.getName());
PEDefinitionElement pe = new PEDefinitionElement(this, name, profile, defn, parent.path());
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
pe.setMustHaveValue(definition.getMustHaveValue());
}
pe.setInFixedValue(definition.hasFixed() || definition.hasPattern() || parent.isInFixedValue());
if (defn.hasSlicing()) {
if (defn.getSlicing().getRules() != SlicingRules.CLOSED) {
res.add(pe);
pe.setSlicer(true);
}
pe.setInFixedValue(definition.hasFixed() || definition.hasPattern() || parent.isInFixedValue());
if (defn.hasSlicing()) {
if (defn.getSlicing().getRules() != SlicingRules.CLOSED) {
res.add(pe);
pe.setSlicer(true);
}
i++;
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
StructureDefinition ext = getExtensionDefinition(list.get(i));
if (ext != null) {
res.add(new PEDefinitionExtension(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, ext, parent.path()));
} else if (isTypeSlicing(defn)) {
res.add(new PEDefinitionTypeSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
i++;
while (i < list.size() && list.get(i).getPath().equals(defn.getPath())) {
StructureDefinition ext = getExtensionDefinition(list.get(i));
if (ext != null) {
res.add(new PEDefinitionExtension(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, ext, parent.path()));
} else if (isTypeSlicing(defn)) {
res.add(new PEDefinitionTypeSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
} else {
if (ProfileUtilities.isComplexExtension(profile) && defn.getPath().endsWith(".extension")) {
res.add(new PEDefinitionSubExtension(this, profile, list.get(i), parent.path()));
} else {
if (ProfileUtilities.isComplexExtension(profile) && defn.getPath().endsWith(".extension")) {
res.add(new PEDefinitionSubExtension(this, profile, list.get(i), parent.path()));
} else {
res.add(new PEDefinitionSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
}
res.add(new PEDefinitionSlice(this, uniquefy(names, list.get(i).getSliceName()), profile, list.get(i), defn, parent.path()));
}
i++;
}
} else {
res.add(pe);
i++;
}
} else {
res.add(pe);
i++;
}
} else {
i++;
Expand Down Expand Up @@ -434,7 +430,10 @@ protected PEDefinition makeChild(PEDefinition parent, StructureDefinition profil
return pe;
}

private boolean passElementPropsCheck(ElementDefinition bdefn) {
private boolean passElementPropsCheck(ElementDefinition bdefn, boolean inExtension) {
if (inExtension) {
return !Utilities.existsInList(bdefn.getBase().getPath(), "Element.id");
}
switch (elementProps) {
case EXTENSION:
return !Utilities.existsInList(bdefn.getBase().getPath(), "Element.id");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
import org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.Type;
import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.profilemodel.PEDefinition.PEDefinitionElementMode;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;

public abstract class PEDefinition {
Expand Down Expand Up @@ -84,7 +86,7 @@ protected PEDefinition(PEBuilder builder, String name, StructureDefinition profi
this.name = name;
this.profile = profile;
this.definition = definition;
this.path = path == null ? name : ppath+"."+name;
this.path = ppath == null ? name : ppath+"."+name;
}


Expand Down Expand Up @@ -392,6 +394,34 @@ public boolean isExtension() {
return false;
}

public String getExtensionUrl() {
return null;
}

public ValueSet valueSet() {
if (definition.getBinding().hasValueSet()) {
return builder.getContext().fetchResource(ValueSet.class, definition.getBinding().getValueSet());
}
return null;
}


public PEBuilder getBuilder() {
return builder;
}

public String typeSummary() {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (PEType t : types()) {
b.append(t.getName());
}
return b.toString();
}


public boolean isSlice() {
return definition.hasSliceName();
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,9 @@ public boolean isExtension() {
return true;
}



public String getExtensionUrl() {
return extension.getUrl();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,8 @@ public boolean isExtension() {
return true;
}

public String getExtensionUrl() {
return ued.getFixed().primitiveValue();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -652,13 +652,15 @@ private ElementDefinition processSimplePathWithOneMatchingElementInDifferential(
}
}
}
template = src.copy().setPath(currentBase.getPath());
template.setSliceName(null);
// temporary work around
if (!"Extension".equals(diffMatches.get(0).getType().get(0).getCode())) {
template.setMin(currentBase.getMin());
template.setMax(currentBase.getMax());
}
if (Utilities.existsInList(currentBase.typeSummary(), "Extension", "Resource")) {
template = src.copy().setPath(currentBase.getPath());
template.setSliceName(null);
// temporary work around
if (!"Extension".equals(diffMatches.get(0).getType().get(0).getCode())) {
template.setMin(currentBase.getMin());
template.setMax(currentBase.getMax());
}
}
}
}
if (template == null)
Expand Down
Loading

0 comments on commit 22eacf9

Please sign in to comment.