Merge remote-tracking branch 'origin/master' into do-20241212-bump-ucum

This commit is contained in:
dotasek 2024-12-16 09:29:29 -05:00
commit 803b50ae55
32 changed files with 1289 additions and 128 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -68,7 +68,7 @@ public class PackageVisitor {
public void alreadyVisited(String pid) throws FHIRException, IOException, EOperationOutcome;
}
private List<String> resourceTypes = new ArrayList<>();
private Set<String> resourceTypes = new HashSet<>();
private List<String> versions = new ArrayList<>();
private boolean corePackages;
private boolean oldVersions;
@ -79,16 +79,16 @@ public class PackageVisitor {
private String cache;
private int step;
public List<String> getResourceTypes() {
public Set<String> getResourceTypes() {
return resourceTypes;
}
public void setResourceTypes(List<String> resourceTypes) {
public void setResourceTypes(Set<String> resourceTypes) {
this.resourceTypes = resourceTypes;
}
public void setResourceTypes(String... resourceTypes) {
this.resourceTypes = new ArrayList<String>();
this.resourceTypes = new HashSet<String>();
for (String s : resourceTypes) {
this.resourceTypes.add(s);
}

View File

@ -0,0 +1,782 @@
package org.hl7.fhir.convertors.analytics;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import org.hl7.fhir.convertors.analytics.PackageVisitor.IPackageVisitorProcessor;
import org.hl7.fhir.convertors.analytics.PackageVisitor.PackageContext;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext.SimpleWorkerContextBuilder;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.elementmodel.ValidatedFragment;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.StringPair;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
import org.hl7.fhir.utilities.http.ManagedWebAccess;
import org.hl7.fhir.utilities.http.ManagedWebAccess.WebAccessPolicy;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.xml.sax.SAXException;
public class TestGenerationDataGenerator implements IPackageVisitorProcessor {
private static class Counter {
private int key;
private int count;
}
private Map<String, Set<String>> hashes = new HashMap<String, Set<String>>();
private Map<String, Counter> elements = new HashMap<String, Counter>();
private Map<String, Counter> types = new HashMap<String, Counter>();
private Map<String, IWorkerContext> contexts= new HashMap<>();
private Connection conn;
private PreparedStatement psqlE;
private PreparedStatement psqlT;
private PreparedStatement psqlV;
private int keyV = 0;
private int keyT = 0;
private int keyE = 0;
private PreparedStatement psqlEC;
private PreparedStatement psqlET;
@Override
public void alreadyVisited(String pid) {
}
@Override
public Object startPackage(PackageContext ctxt) {
return null;
}
@Override
public void processResource(PackageContext ctxt, Object context, String type, String id, byte[] content) throws FHIRException, IOException, EOperationOutcome {
String version = ctxt.getNpm().fhirVersion();
IWorkerContext worker = contexts.get(version);
if (worker == null) {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().build();
NpmPackage npm = pcm.loadPackage(VersionUtilities.packageForVersion(version));
SimpleWorkerContext swc = new SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).fromPackage(npm);
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());
} catch (SQLException e) {
throw new FHIRException(e);
}
}
}
private void processElement(Element element) throws SQLException {
String id = element.getProperty().getDefinition().getId();
switch (element.fhirType()) {
case "Address":
recordValue(id, "Address", getValues(element, "use", "type", "text", "line", "city", "district", "state", "postalCode", "country"));
break;
case "Age":
recordValue(id, "Age", getValues(element, "value", "comparator", "unit", "system", "code"));
break;
case "Annotation":
recordValue(id, "Annotation", getValues(element, "author", "time", "text"));
break;
case "Attachment":
recordValue(id, "Attachment", getValues(element, "contentType", "language", "data", "url", "size", "hash", "title"));
break;
case "CodeableConcept":
break;
case "CodeableReference":
break;
case "Coding":
recordValue(id, "Coding", getValues(element, "system", "version", "code", "display"));
break;
case "ContactPoint":
recordValue(id, "ContactPoint", getValues(element, "system", "value", "use", "rank"));
break;
case "Count":
recordValue(id, "Count", getValues(element, "value", "comparator", "unit", "system", "code"));
break;
case "Distance":
recordValue(id, "Distance", getValues(element, "value", "comparator", "unit", "system", "code"));
break;
case "Duration":
recordValue(id, "Duration", getValues(element, "value", "comparator", "unit", "system", "code"));
break;
case "HumanName":
recordValue(id, "Address", getValues(element, "use", "text", "family", "given", "prefix", "suffix"));
break;
case "Identifier":
recordValue(id, "Identifier", getValues(element, "use", "type", "system", "value"));
break;
case "Money":
recordValue(id, "Money", getValues(element, "value", "currency"));
break;
case "Period":
recordValue(id, "Period", getValues(element, "start", "end"));
break;
case "Quantity":
recordValue(id, "Quantity", getValues(element, "value", "comparator", "unit", "system", "code"));
break;
case "Range":
case "Ratio":
case "RatioRange":
case "Reference":
case "SampledData":
case "Signature":
case "Timing":
case "RelatedArtifact":
case "DataRequirement":
case "Expression":
break;
case "xhtml":
case "id":
case "canonical":
case "boolean":
case "code":
case "uri":
case "instant":
break;
default:
if (element.isPrimitive()) {
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.isResource() || !Utilities.existsInList(child.fhirType(), "Bundle", "CapabilityStatement", "CodeSystem", "ConceptMap", "GraphDefinition", "ImplementationGuide", "MessageHeader", "NamingSystem", "OperationDefinition", "OperationOutcome", "Parameters", "SearchParameter", "StructureDefinition", "StructureMap", "TerminologyCapabilities", "ValueSet")) {
processElement(child);
}
}
}
}
}
}
private String[] getValues(Element element, String... names) {
List<String> values = new ArrayList<>();
for (String name : names) {
List<Element> children = element.getChildren(name);
if (!children.isEmpty()) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("~");
for (Element child : children) {
if (child.hasPrimitiveValue()) {
b.append(child.primitiveValue());
}
}
if (b.length() > 0) {
values.add(name+":"+b.toString());
}
}
}
return values.toArray(new String[0]);
}
public void start(String filename) throws SQLException, IOException {
ManagedFileAccess.file(filename).delete();
conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE TestElements (ElementKey int NOT NULL, ElementId nvarchar NOT NULL, Count int NULL, PRIMARY KEY (ElementKey))");
stmt.execute("CREATE INDEX TestElementsElement ON TestElements ( ElementId )");
stmt.execute("CREATE TABLE TestTypes (TypeKey int NOT NULL, TypeName nvarchar NOT NULL, Count int NULL, PRIMARY KEY (TypeKey))");
stmt.execute("CREATE INDEX TestTypesType ON TestTypes ( TypeName )");
stmt.execute("CREATE TABLE TestValues (ValueKey int NOT NULL, ElementKey int NOT NULL, TypeKey int NOT NULL, ValueData nvarchar NOT NULL, PRIMARY KEY (ValueKey))");
stmt.execute("CREATE INDEX TestValueElement ON TestValues ( ElementKey, TypeKey)");
psqlE = conn.prepareStatement("Insert into TestElements (ElementKey, ElementId) values (?, ?)");
psqlT = conn.prepareStatement("Insert into TestTypes (TypeKey, TypeName) values (?, ?)");
psqlV = conn.prepareStatement("Insert into TestValues (ValueKey, ElementKey, TypeKey, ValueData) values (?, ?, ?, ?)");
psqlEC = conn.prepareStatement("Update TestElements set Count = ? where ElementKey = ?");
psqlET = conn.prepareStatement("Update TestTypes set Count = ? where TypeKey = ?");
}
private void store(String path, String type, String[] values) throws SQLException {
Counter cE = elements.get(path);
if (cE != null) {
cE.count++;
psqlEC.setInt(1, cE.count);
psqlEC.setInt(2, cE.key);
psqlEC.execute();
} else {
keyE++;
cE = new Counter();
cE.key = keyE;
cE.count = 1;
elements.put(path, cE);
psqlE.setInt(1, cE.key);
psqlE.setString(2, path);
psqlE.execute();
}
Counter cT = types.get(type);
if (cT != null) {
cT.count++;
psqlET.setInt(1, cT.count);
psqlET.setInt(2, cT.key);
psqlET.execute();
} else {
keyT++;
cT = new Counter();
cT.key = keyT;
cT.count = 1;
types.put(type, cT);
psqlT.setInt(1, cT.key);
psqlT.setString(2, type);
psqlT.execute();
}
psqlV.setInt(1, keyE++);
psqlV.setInt(2, cE.key);
psqlV.setInt(3, cT.key);
psqlV.setString(4, CommaSeparatedStringBuilder.join("|:|",values));
psqlV.execute();
}
private void recordValue(String path, String type, String... values) throws SQLException {
StringBuilder v = new StringBuilder();
v.append(type);
v.append("|");
for (String s : values) {
v.append(s);
v.append("|");
}
Set<String> hashset = hashes.get(path);
if (hashset == null) {
hashset = new HashSet<String>();
hashes.put(path, hashset);
}
String s= v.toString();
if (!hashset.contains(s)) {
hashset.add(s);
store(path, type, values);
}
}
@Override
public void finishPackage(PackageContext ctxt) {
}
public static void main(String[] args) throws Exception {
new TestGenerationDataGenerator().execute();
// new TestGenerationDataGenerator().offAirWExecute();
}
private void offAirWExecute() throws FHIRException, IOException, EOperationOutcome, SQLException {
ManagedWebAccess.setAccessPolicy(WebAccessPolicy.PROHIBITED);
start("/Users/grahamegrieve/temp/testdata.db");
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().build();
System.out.println("Processing");
for (String pid : pcm.listPackages()) {
System.out.println(pid);
NpmPackage npm = pcm.loadPackage(pid);
try {
processPackage(npm);
} catch (Exception e) {
System.out.println(" "+e.getMessage());
}
}
System.out.print("Done");
}
private void processPackage(NpmPackage npm) throws IOException, FHIRException, EOperationOutcome {
String fv = npm.fhirVersion();
String v = npm.version();
PackageContext ctxt = new PackageContext(npm.name()+"#"+v, npm, fv);
boolean ok = false;
Object context = null;
context = startPackage(ctxt);
ok = true;
if (ok) {
int c = 0;
Set<String> resourceTypes = new HashSet<String>();
addR5ResourceNames(resourceTypes);
addR4ResourceNames(resourceTypes);
addR3ResourceNames(resourceTypes);
for (String type : resourceTypes) {
List<String> rt = new ArrayList<String>();
rt.add(type);
for (StringPair s : npm.listAllResources(rt)) {
c++;
processResource(ctxt, context, type, s.getName(), TextFile.streamToBytes(npm.load(s.getName(), s.getValue())));
}
}
}
finishPackage(ctxt);
}
private void execute() throws IOException, ParserConfigurationException, SAXException, FHIRException, EOperationOutcome, SQLException {
start("/Users/grahamegrieve/temp/testdata.db");
PackageVisitor pv = new PackageVisitor();
addR5ResourceNames(pv.getResourceTypes());
addR4ResourceNames(pv.getResourceTypes());
addR3ResourceNames(pv.getResourceTypes());
pv.setOldVersions(false);
pv.setCorePackages(true);
pv.setProcessor(this);
pv.visitPackages();
System.out.println("Done");
}
private void addR5ResourceNames(Set<String> set) {
set.add("Account");
set.add("ActivityDefinition");
set.add("ActorDefinition");
set.add("AdministrableProductDefinition");
set.add("AdverseEvent");
set.add("AllergyIntolerance");
set.add("Appointment");
set.add("AppointmentResponse");
set.add("ArtifactAssessment");
set.add("AuditEvent");
set.add("Basic");
// set.add("Binary");
set.add("BiologicallyDerivedProduct");
set.add("BiologicallyDerivedProductDispense");
set.add("BodyStructure");
// set.add("Bundle");
// set.add("CapabilityStatement");
set.add("CarePlan");
set.add("CareTeam");
set.add("ChargeItem");
set.add("ChargeItemDefinition");
set.add("Citation");
set.add("Claim");
set.add("ClaimResponse");
set.add("ClinicalImpression");
set.add("ClinicalUseDefinition");
// set.add("CodeSystem");
set.add("Communication");
set.add("CommunicationRequest");
set.add("CompartmentDefinition");
set.add("Composition");
// set.add("ConceptMap");
set.add("Condition");
set.add("ConditionDefinition");
set.add("Consent");
set.add("Contract");
set.add("Coverage");
set.add("CoverageEligibilityRequest");
set.add("CoverageEligibilityResponse");
set.add("DetectedIssue");
set.add("Device");
set.add("DeviceAssociation");
set.add("DeviceDefinition");
set.add("DeviceDispense");
set.add("DeviceMetric");
set.add("DeviceRequest");
set.add("DeviceUsage");
set.add("DiagnosticReport");
set.add("DocumentReference");
set.add("Encounter");
set.add("EncounterHistory");
set.add("Endpoint");
set.add("EnrollmentRequest");
set.add("EnrollmentResponse");
set.add("EpisodeOfCare");
set.add("EventDefinition");
set.add("Evidence");
set.add("EvidenceReport");
set.add("EvidenceVariable");
set.add("ExampleScenario");
set.add("ExplanationOfBenefit");
set.add("FamilyMemberHistory");
set.add("Flag");
set.add("FormularyItem");
set.add("GenomicStudy");
set.add("Goal");
// set.add("GraphDefinition");
set.add("Group");
set.add("GuidanceResponse");
set.add("HealthcareService");
set.add("ImagingSelection");
set.add("ImagingStudy");
set.add("Immunization");
set.add("ImmunizationEvaluation");
set.add("ImmunizationRecommendation");
// set.add("ImplementationGuide");
set.add("Ingredient");
set.add("InsurancePlan");
set.add("InventoryItem");
set.add("InventoryReport");
set.add("Invoice");
set.add("Library");
set.add("Linkage");
set.add("List");
set.add("Location");
set.add("ManufacturedItemDefinition");
set.add("Measure");
set.add("MeasureReport");
set.add("Medication");
set.add("MedicationAdministration");
set.add("MedicationDispense");
set.add("MedicationKnowledge");
set.add("MedicationRequest");
set.add("MedicationStatement");
set.add("MedicinalProductDefinition");
set.add("MessageDefinition");
// set.add("MessageHeader");
set.add("MolecularSequence");
// set.add("NamingSystem");
set.add("NutritionIntake");
set.add("NutritionOrder");
set.add("NutritionProduct");
set.add("Observation");
set.add("ObservationDefinition");
// set.add("OperationDefinition");
// set.add("OperationOutcome");
set.add("Organization");
set.add("OrganizationAffiliation");
set.add("PackagedProductDefinition");
// set.add("Parameters");
set.add("Patient");
set.add("PaymentNotice");
set.add("PaymentReconciliation");
set.add("Permission");
set.add("Person");
set.add("PlanDefinition");
set.add("Practitioner");
set.add("PractitionerRole");
set.add("Procedure");
set.add("Provenance");
set.add("Questionnaire");
set.add("QuestionnaireResponse");
set.add("RegulatedAuthorization");
set.add("RelatedPerson");
set.add("RequestOrchestration");
set.add("Requirements");
set.add("ResearchStudy");
set.add("ResearchSubject");
set.add("RiskAssessment");
set.add("Schedule");
// set.add("SearchParameter");
set.add("ServiceRequest");
set.add("Slot");
set.add("Specimen");
set.add("SpecimenDefinition");
// set.add("StructureDefinition");
// set.add("StructureMap");
set.add("Subscription");
set.add("SubscriptionStatus");
set.add("SubscriptionTopic");
set.add("Substance");
set.add("SubstanceDefinition");
set.add("SubstanceNucleicAcid");
set.add("SubstancePolymer");
set.add("SubstanceProtein");
set.add("SubstanceReferenceInformation");
set.add("SubstanceSourceMaterial");
set.add("SupplyDelivery");
set.add("SupplyRequest");
set.add("Task");
// set.add("TerminologyCapabilities");
set.add("TestPlan");
set.add("TestReport");
set.add("TestScript");
set.add("Transport");
// set.add("ValueSet");
set.add("VerificationResult");
set.add("VisionPrescription");
}
private void addR4ResourceNames(Set<String> set) {
set.add("Account");
set.add("ActivityDefinition");
set.add("AdverseEvent");
set.add("AllergyIntolerance");
set.add("Appointment");
set.add("AppointmentResponse");
set.add("AuditEvent");
set.add("Basic");
// set.add("Binary");
set.add("BiologicallyDerivedProduct");
set.add("BodyStructure");
// set.add("Bundle");
// set.add("CapabilityStatement");
set.add("CarePlan");
set.add("CareTeam");
set.add("CatalogEntry");
set.add("ChargeItem");
set.add("ChargeItemDefinition");
set.add("Claim");
set.add("ClaimResponse");
set.add("ClinicalImpression");
// set.add("CodeSystem");
set.add("Communication");
set.add("CommunicationRequest");
set.add("CompartmentDefinition");
set.add("Composition");
// set.add("ConceptMap");
set.add("Condition");
set.add("Consent");
set.add("Contract");
set.add("Coverage");
set.add("CoverageEligibilityRequest");
set.add("CoverageEligibilityResponse");
set.add("DetectedIssue");
set.add("Device");
set.add("DeviceDefinition");
set.add("DeviceMetric");
set.add("DeviceRequest");
set.add("DeviceUseStatement");
set.add("DiagnosticReport");
set.add("DocumentManifest");
set.add("DocumentReference");
set.add("EffectEvidenceSynthesis");
set.add("Encounter");
set.add("Endpoint");
set.add("EnrollmentRequest");
set.add("EnrollmentResponse");
set.add("EpisodeOfCare");
set.add("EventDefinition");
set.add("Evidence");
set.add("EvidenceVariable");
set.add("ExampleScenario");
set.add("ExplanationOfBenefit");
set.add("FamilyMemberHistory");
set.add("Flag");
set.add("Goal");
// set.add("GraphDefinition");
set.add("Group");
set.add("GuidanceResponse");
set.add("HealthcareService");
set.add("ImagingStudy");
set.add("Immunization");
set.add("ImmunizationEvaluation");
set.add("ImmunizationRecommendation");
// set.add("ImplementationGuide");
set.add("InsurancePlan");
set.add("Invoice");
set.add("Library");
set.add("Linkage");
set.add("List");
set.add("Location");
set.add("Measure");
set.add("MeasureReport");
set.add("Media");
set.add("Medication");
set.add("MedicationAdministration");
set.add("MedicationDispense");
set.add("MedicationKnowledge");
set.add("MedicationRequest");
set.add("MedicationStatement");
set.add("MedicinalProduct");
set.add("MedicinalProductAuthorization");
set.add("MedicinalProductContraindication");
set.add("MedicinalProductIndication");
set.add("MedicinalProductIngredient");
set.add("MedicinalProductInteraction");
set.add("MedicinalProductManufactured");
set.add("MedicinalProductPackaged");
set.add("MedicinalProductPharmaceutical");
set.add("MedicinalProductUndesirableEffect");
set.add("MessageDefinition");
// set.add("MessageHeader");
set.add("MolecularSequence");
// set.add("NamingSystem");
set.add("NutritionOrder");
set.add("Observation");
set.add("ObservationDefinition");
// set.add("OperationDefinition");
// set.add("OperationOutcome");
set.add("Organization");
set.add("OrganizationAffiliation");
// set.add("Parameters");
set.add("Patient");
set.add("PaymentNotice");
set.add("PaymentReconciliation");
set.add("Person");
set.add("PlanDefinition");
set.add("Practitioner");
set.add("PractitionerRole");
set.add("Procedure");
set.add("Provenance");
set.add("Questionnaire");
set.add("QuestionnaireResponse");
set.add("RelatedPerson");
set.add("RequestGroup");
set.add("ResearchDefinition");
set.add("ResearchElementDefinition");
set.add("ResearchStudy");
set.add("ResearchSubject");
set.add("RiskAssessment");
set.add("RiskEvidenceSynthesis");
set.add("Schedule");
// set.add("SearchParameter");
set.add("ServiceRequest");
set.add("Slot");
set.add("Specimen");
set.add("SpecimenDefinition");
// set.add("StructureDefinition");
// set.add("StructureMap");
set.add("Subscription");
set.add("Substance");
set.add("SubstancePolymer");
set.add("SubstanceProtein");
set.add("SubstanceReferenceInformation");
set.add("SubstanceSpecification");
set.add("SubstanceSourceMaterial");
set.add("SupplyDelivery");
set.add("SupplyRequest");
set.add("Task");
set.add("TerminologyCapabilities");
set.add("TestReport");
set.add("TestScript");
// set.add("ValueSet");
set.add("VerificationResult");
set.add("VisionPrescription");
}
private void addR3ResourceNames(Set<String> set) {
set.add("Account");
set.add("ActivityDefinition");
set.add("AllergyIntolerance");
set.add("AdverseEvent");
set.add("Appointment");
set.add("AppointmentResponse");
set.add("AuditEvent");
set.add("Basic");
// set.add("Binary");
set.add("BodySite");
// set.add("Bundle");
// set.add("CapabilityStatement");
set.add("CarePlan");
set.add("CareTeam");
set.add("ChargeItem");
set.add("Claim");
set.add("ClaimResponse");
set.add("ClinicalImpression");
// set.add("CodeSystem");
set.add("Communication");
set.add("CommunicationRequest");
set.add("CompartmentDefinition");
set.add("Composition");
// set.add("ConceptMap");
set.add("Condition");
set.add("Consent");
set.add("Contract");
set.add("Coverage");
set.add("DataElement");
set.add("DetectedIssue");
set.add("Device");
set.add("DeviceComponent");
set.add("DeviceMetric");
set.add("DeviceRequest");
set.add("DeviceUseStatement");
set.add("DiagnosticReport");
set.add("DocumentManifest");
set.add("DocumentReference");
set.add("EligibilityRequest");
set.add("EligibilityResponse");
set.add("Encounter");
set.add("Endpoint");
set.add("EnrollmentRequest");
set.add("EnrollmentResponse");
set.add("EpisodeOfCare");
set.add("ExpansionProfile");
set.add("ExplanationOfBenefit");
set.add("FamilyMemberHistory");
set.add("Flag");
set.add("Goal");
// set.add("GraphDefinition");
set.add("Group");
set.add("GuidanceResponse");
set.add("HealthcareService");
set.add("ImagingManifest");
set.add("ImagingStudy");
set.add("Immunization");
set.add("ImmunizationRecommendation");
// set.add("ImplementationGuide");
set.add("Library");
set.add("Linkage");
set.add("List");
set.add("Location");
set.add("Measure");
set.add("MeasureReport");
set.add("Media");
set.add("Medication");
set.add("MedicationAdministration");
set.add("MedicationDispense");
set.add("MedicationRequest");
set.add("MedicationStatement");
set.add("MessageDefinition");
// set.add("MessageHeader");
// set.add("NamingSystem");
set.add("NutritionOrder");
set.add("Observation");
// set.add("OperationDefinition");
// set.add("OperationOutcome");
set.add("Organization");
// set.add("Parameters");
set.add("Patient");
set.add("PaymentNotice");
set.add("PaymentReconciliation");
set.add("Person");
set.add("PlanDefinition");
set.add("Practitioner");
set.add("PractitionerRole");
set.add("Procedure");
set.add("ProcedureRequest");
set.add("ProcessRequest");
set.add("ProcessResponse");
set.add("Provenance");
set.add("Questionnaire");
set.add("QuestionnaireResponse");
set.add("ReferralRequest");
set.add("RelatedPerson");
set.add("RequestGroup");
set.add("ResearchStudy");
set.add("ResearchSubject");
set.add("RiskAssessment");
set.add("Schedule");
// set.add("SearchParameter");
set.add("Sequence");
set.add("ServiceDefinition");
set.add("Slot");
set.add("Specimen");
// set.add("StructureDefinition");
// set.add("StructureMap");
set.add("Subscription");
set.add("Substance");
set.add("SupplyDelivery");
set.add("SupplyRequest");
set.add("Task");
set.add("TestScript");
set.add("TestReport");
// set.add("ValueSet");
set.add("VisionPrescription");
}
}

View File

@ -477,7 +477,7 @@ public class ValueSet40_50 {
for (org.hl7.fhir.r4.model.Extension t : src.getExtension()) {
if ("http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property".equals(t.getUrl())) {
ConceptPropertyComponent prop = tgt.addProperty();
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(t, prop, "code", "value[x]");
ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(t, prop, "code", "value[x]", "value");
prop.setCode(t.getExtensionString("code"));
if (t.hasExtension("value")) {
prop.setValue(ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().convertType(t.getExtensionByUrl("value").getValue()));

View File

@ -57,14 +57,14 @@ public class XVersionLoader {
public static void saveXml(String version, Resource resource, OutputStream stream) throws FHIRFormatError, IOException {
if (Utilities.noString(version)) {
new org.hl7.fhir.r5.formats.XmlParser().compose(stream, resource, true);
new org.hl7.fhir.r5.formats.XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(stream, resource);
}
switch (VersionUtilities.getMajMin(version)) {
case "1.0":
new org.hl7.fhir.dstu2.formats.XmlParser().compose(stream, VersionConvertorFactory_10_50.convertResource(resource), true);
return;
case "1.4":
new org.hl7.fhir.dstu2016may.formats.XmlParser().compose(stream, VersionConvertorFactory_14_50.convertResource(resource), true);
new org.hl7.fhir.dstu2016may.formats.XmlParser(true, true).compose(stream, VersionConvertorFactory_14_50.convertResource(resource), true);
return;
case "3.0":
new org.hl7.fhir.dstu3.formats.XmlParser().compose(stream, VersionConvertorFactory_30_50.convertResource(resource), true);
@ -73,7 +73,7 @@ public class XVersionLoader {
new org.hl7.fhir.r4.formats.XmlParser().compose(stream, VersionConvertorFactory_40_50.convertResource(resource), true);
return;
case "5.0":
new org.hl7.fhir.r5.formats.XmlParser().compose(stream, resource, true);
new org.hl7.fhir.r5.formats.XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(stream, resource);
return;
}
throw new FHIRException("Unknown version " + version + " loading resource");

View File

@ -49,6 +49,14 @@ public class XmlParser extends XmlParserBase {
setAllowUnknownContent(allowUnknownContent);
}
public XmlParser(boolean allowUnknownContent, boolean pretty) {
super();
setAllowUnknownContent(allowUnknownContent);
if (pretty) {
setOutputStyle(OutputStyle.PRETTY);
}
}
protected boolean parseElementContent(int eventType, XmlPullParser xpp, Element res)
throws XmlPullParserException, IOException, FHIRFormatError {
if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("extension"))

View File

@ -361,7 +361,7 @@ public class PEBuilder {
if (!defn.getMax().equals("0") && (allFixed || include(defn))) {
if (passElementPropsCheck(defn) && !Utilities.existsInList(defn.getName(), omitList)) {
if (defn.getType().size() > 1) {
// DebugUtilities.breakpoint();
// Debug/Utilities.breakpoint();
i++;
} else {
String name = uniquefy(names, defn.getName());

View File

@ -217,6 +217,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
@With
private final org.hl7.fhir.r5.context.ILoggingService loggingService;
private boolean defaultExpParams;
public SimpleWorkerContextBuilder() {
cacheTerminologyClientErrors = false;
@ -247,6 +248,9 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
context.setUserAgent(userAgent);
context.setLogger(loggingService);
context.cacheResource(new org.hl7.fhir.r5.formats.JsonParser().parse(MagicResources.spdxCodesAsData()));
if (defaultExpParams) {
context.setExpansionParameters(makeExpProfile());
}
return context;
}
@ -257,6 +261,12 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
context.loadFromPackage(pi, null);
return build(context);
}
private Parameters makeExpProfile() {
Parameters ep = new Parameters();
ep.addParameter("cache-id", UUID.randomUUID().toString().toLowerCase());
return ep;
}
public SimpleWorkerContext fromPackage(NpmPackage pi, IContextResourceLoader loader, boolean genSnapshots) throws IOException, FHIRException {
SimpleWorkerContext context = getSimpleWorkerContextInstance();
@ -265,6 +275,9 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
context.terminologyClientManager.setFactory(loader.txFactory());
context.loadFromPackage(pi, loader);
context.finishLoading(genSnapshots);
if (defaultExpParams) {
context.setExpansionParameters(makeExpProfile());
}
return build(context);
}
@ -321,6 +334,11 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
public SimpleWorkerContext fromNothing() throws FHIRException, IOException {
return build();
}
public SimpleWorkerContextBuilder withDefaultParams() {
defaultExpParams = true;
return this;
}
}
private void loadDefinitionItem(String name, InputStream stream, IContextResourceLoader loader, ILoadFilter filter, PackageInformation pi) throws IOException, FHIRException {

View File

@ -972,18 +972,19 @@ public class JsonParser extends ParserBase {
json.name(name);
}
String type = item.getType();
if (Utilities.existsInList(type, "boolean"))
if (Utilities.existsInList(type, "boolean")) {
json.value(item.getValue().trim().equals("true") ? new Boolean(true) : new Boolean(false));
else if (Utilities.existsInList(type, "integer", "unsignedInt", "positiveInt"))
} else if (Utilities.existsInList(type, "integer", "unsignedInt", "positiveInt")) {
json.value(new Integer(item.getValue()));
else if (Utilities.existsInList(type, "decimal"))
} else if (Utilities.existsInList(type, "decimal")) {
try {
json.value(new BigDecimal(item.getValue()));
} catch (Exception e) {
throw new NumberFormatException(context.formatMessage(I18nConstants.ERROR_WRITING_NUMBER__TO_JSON, item.getValue()));
}
else
} else {
json.value(item.getValue());
}
}
private void compose(String path, Element element) throws IOException {

View File

@ -2,8 +2,10 @@ package org.hl7.fhir.r5.elementmodel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.checkerframework.checker.units.qual.cd;
@ -60,6 +62,18 @@ public class LanguageUtils {
public static final List<String> TRANSLATION_SUPPLEMENT_RESOURCE_TYPES = Arrays.asList("CodeSystem", "StructureDefinition", "Questionnaire");
public static class TranslationUnitCollection {
List<TranslationUnit> list= new ArrayList<>();
Map<String, TranslationUnit> map = new HashMap<>();
public void add(TranslationUnit tu) {
String key = tu.getId()+"||"+tu.getSrcText();
if (!map.containsKey(key)) {
map.put(key, tu);
list.add(tu);
}
}
}
IWorkerContext context;
private List<String> crlist;
@ -70,24 +84,25 @@ public class LanguageUtils {
}
public void generateTranslations(Element resource, LanguageProducerLanguageSession session) {
translate(null, resource, session);
translate(null, resource, session, resource.fhirType());
}
private void translate(Element parent, Element element, LanguageProducerLanguageSession langSession) {
private void translate(Element parent, Element element, LanguageProducerLanguageSession langSession, String path) {
String npath = pathForElement(path, element);
if (element.isPrimitive() && isTranslatable(element)) {
String base = element.primitiveValue();
if (base != null) {
String translation = getSpecialTranslation(parent, element, langSession.getTargetLang());
String translation = getSpecialTranslation(path, parent, element, langSession.getTargetLang());
if (translation == null) {
translation = element.getTranslation(langSession.getTargetLang());
}
langSession.entry(new TextUnit(pathForElement(element), contextForElement(element), base, translation));
langSession.entry(new TextUnit(npath, contextForElement(element), base, translation));
}
}
for (Element c: element.getChildren()) {
if (!c.getName().equals("designation")) {
translate(element, c, langSession);
translate(element, c, langSession, npath);
}
}
}
@ -96,17 +111,18 @@ public class LanguageUtils {
throw new Error("Not done yet");
}
private String getSpecialTranslation(Element parent, Element element, String targetLang) {
private String getSpecialTranslation(String path, Element parent, Element element, String targetLang) {
if (parent == null) {
return null;
}
if (Utilities.existsInList(pathForElement(parent), "CodeSystem.concept", "CodeSystem.concept.concept") && "CodeSystem.concept.display".equals(pathForElement(element))) {
String npath = parent.getBasePath();
if (Utilities.existsInList(npath, "CodeSystem.concept", "CodeSystem.concept.concept") && "CodeSystem.concept.display".equals(element.getBasePath())) {
return getDesignationTranslation(parent, targetLang);
}
if (Utilities.existsInList(pathForElement(parent), "ValueSet.compose.include.concept") && "ValueSet.compose.include.concept.display".equals(pathForElement(element))) {
if (Utilities.existsInList(npath, "ValueSet.compose.include.concept") && "ValueSet.compose.include.concept.display".equals(element.getBasePath())) {
return getDesignationTranslation(parent, targetLang);
}
if (Utilities.existsInList(pathForElement(parent), "ValueSet.expansion.contains", "ValueSet.expansion.contains.contains") && "ValueSet.expansion.contains.display".equals(pathForElement(element))) {
if (Utilities.existsInList(npath, "ValueSet.expansion.contains", "ValueSet.expansion.contains.contains") && "ValueSet.expansion.contains.display".equals(element.getBasePath())) {
return getDesignationTranslation(parent, targetLang);
}
return null;
@ -126,9 +142,13 @@ public class LanguageUtils {
return element.getProperty().isTranslatable();
}
private String pathForElement(Element element) {
String bp = element.getBasePath();
return pathForElement(bp, element.getProperty().getStructure().getType());
private String pathForElement(String path, Element element) {
if (element.getSpecial() != null) {
String bp = element.getBasePath();
return pathForElement(bp, element.getProperty().getStructure().getType());
} else {
return (path == null ? element.getName() : path+"."+element.getName());
}
}
private String pathForElement(String path, String type) {
@ -151,7 +171,7 @@ public class LanguageUtils {
public int importFromTranslations(Element resource, List<TranslationUnit> translations) {
return importFromTranslations(null, resource, translations, new HashSet<>());
return importFromTranslations(resource.fhirType(), null, resource, translations, new HashSet<>());
}
public int importFromTranslations(Element resource, List<TranslationUnit> translations, List<ValidationMessage> messages) {
@ -160,7 +180,7 @@ public class LanguageUtils {
if (resource.fhirType().equals("StructureDefinition")) {
r = importFromTranslationsForSD(null, resource, translations, usedUnits);
} else {
r = importFromTranslations(null, resource, translations, usedUnits);
r = importFromTranslations(null, null, resource, translations, usedUnits);
}
for (TranslationUnit t : translations) {
if (!usedUnits.contains(t)) {
@ -282,13 +302,13 @@ public class LanguageUtils {
return Utilities.existsInList(element.fhirType(), "string", "markdown");
}
private int importFromTranslations(Element parent, Element element, List<TranslationUnit> translations, Set<TranslationUnit> usedUnits) {
private int importFromTranslations(String path, Element parent, Element element, List<TranslationUnit> translations, Set<TranslationUnit> usedUnits) {
String npath = pathForElement(path, element);
int t = 0;
if (element.isPrimitive() && isTranslatable(element)) {
String base = element.primitiveValue();
if (base != null) {
String path = pathForElement(element);
Set<TranslationUnit> tlist = findTranslations(path, base, translations);
Set<TranslationUnit> tlist = findTranslations(npath, base, translations);
for (TranslationUnit translation : tlist) {
t++;
if (!handleAsSpecial(parent, element, translation)) {
@ -302,7 +322,7 @@ public class LanguageUtils {
List<Element> childrenCopy = List.copyOf(element.getChildren());
for (Element c : childrenCopy) {
if (!c.getName().equals("designation")) {
t = t + importFromTranslations(element, c, translations, usedUnits);
t = t + importFromTranslations(npath, element, c, translations, usedUnits);
}
}
return t;
@ -312,13 +332,13 @@ public class LanguageUtils {
if (parent == null) {
return false;
}
if (Utilities.existsInList(pathForElement(parent), "CodeSystem.concept", "CodeSystem.concept.concept") && "CodeSystem.concept.display".equals(pathForElement(element))) {
if (Utilities.existsInList(parent.getBasePath(), "CodeSystem.concept", "CodeSystem.concept.concept") && "CodeSystem.concept.display".equals(element.getBasePath())) {
return setDesignationTranslation(parent, translation.getLanguage(), translation.getTgtText());
}
if (Utilities.existsInList(pathForElement(parent), "ValueSet.compose.include.concept") && "ValueSet.compose.include.concept.display".equals(pathForElement(element))) {
if (Utilities.existsInList(parent.getBasePath(), "ValueSet.compose.include.concept") && "ValueSet.compose.include.concept.display".equals(element.getBasePath())) {
return setDesignationTranslation(parent, translation.getLanguage(), translation.getTgtText());
}
if (Utilities.existsInList(pathForElement(parent), "ValueSet.expansion.contains", "ValueSet.expansion.contains.contains") && "ValueSet.expansion.contains.display".equals(pathForElement(element))) {
if (Utilities.existsInList(parent.getBasePath(), "ValueSet.expansion.contains", "ValueSet.expansion.contains.contains") && "ValueSet.expansion.contains.display".equals(element.getBasePath())) {
return setDesignationTranslation(parent, translation.getLanguage(), translation.getTgtText());
}
return false;
@ -500,7 +520,7 @@ public class LanguageUtils {
if (res.hasUserData(UserDataNames.LANGUTILS_ORPHAN)) {
List<TranslationUnit> orphans = (List<TranslationUnit>) res.getUserData(UserDataNames.LANGUTILS_ORPHAN);
for (TranslationUnit t : orphans) {
list.add(new TranslationUnit(lang, "!!"+t.getId(), t.getContext1(), t.getSrcText(), t.getTgtText()));
list.add(new TranslationUnit(lang, "!!"+t.getId(), t.getContext(), t.getSrcText(), t.getTgtText()));
}
}
} else {
@ -512,7 +532,7 @@ public class LanguageUtils {
if (cs.hasUserData(UserDataNames.LANGUTILS_ORPHAN)) {
List<TranslationUnit> orphans = (List<TranslationUnit>) cs.getUserData(UserDataNames.LANGUTILS_ORPHAN);
for (TranslationUnit t : orphans) {
list.add(new TranslationUnit(lang, "!!"+t.getId(), t.getContext1(), t.getSrcText(), t.getTgtText()));
list.add(new TranslationUnit(lang, "!!"+t.getId(), t.getContext(), t.getSrcText(), t.getTgtText()));
}
}
}
@ -601,14 +621,15 @@ public class LanguageUtils {
}
public List<TranslationUnit> generateTranslations(Element e, String lang) {
List<TranslationUnit> list = new ArrayList<>();
generateTranslations(e, lang, list);
return list;
TranslationUnitCollection list = new TranslationUnitCollection();
generateTranslations(e, lang, list, e.fhirType());
return list.list;
}
private void generateTranslations(Element e, String lang, List<TranslationUnit> list) {
private void generateTranslations(Element e, String lang, TranslationUnitCollection list, String path) {
String npath = pathForElement(path, e);
if (e.getProperty().isTranslatable()) {
String id = pathForElement(e); // .getProperty().getDefinition().getPath();
String id = npath; // .getProperty().getDefinition().getPath();
String context = e.getProperty().getDefinition().getDefinition();
String src = e.primitiveValue();
String tgt = getTranslation(e, lang);
@ -616,7 +637,7 @@ public class LanguageUtils {
}
if (e.hasChildren()) {
for (Element c : e.getChildren()) {
generateTranslations(c, lang, list);
generateTranslations(c, lang, list, npath);
}
}

View File

@ -36,6 +36,7 @@ import java.util.Date;
import java.util.List;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.r5.model.Enumerations.*;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.instance.model.api.IBaseDatatypeElement;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.ICompositeType;
@ -648,6 +649,14 @@ public class Coding extends DataType implements IBaseCoding, ICompositeType, ICo
}
// end addition
public Coding(ValueSetExpansionContainsComponent cc) {
super();
setSystem(cc.getSystem());
setVersion(cc.getVersion());
setCode(cc.getCode());
setDisplay(cc.getDisplay());
}
public String getVersionedSystem() {
return hasVersion() ? getSystem()+"|"+getVersion() : getSystem();
}

View File

@ -35,7 +35,7 @@ package org.hl7.fhir.r5.model;
public class Constants {
public final static String LOCAL_REF_REGEX = "(Account|ActivityDefinition|ActorDefinition|AdministrableProductDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|ArtifactAssessment|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BiologicallyDerivedProductDispense|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|ChargeItem|ChargeItemDefinition|Citation|Claim|ClaimResponse|ClinicalImpression|ClinicalUseDefinition|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|ConditionDefinition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceAssociation|DeviceDefinition|DeviceDispense|DeviceMetric|DeviceRequest|DeviceUsage|DiagnosticReport|DocumentReference|Encounter|EncounterHistory|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceReport|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|FormularyItem|GenomicStudy|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingSelection|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|Ingredient|InsurancePlan|InventoryItem|InventoryReport|Invoice|Library|Linkage|List|Location|ManufacturedItemDefinition|Measure|MeasureReport|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProductDefinition|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionIntake|NutritionOrder|NutritionProduct|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|PackagedProductDefinition|Parameters|Patient|PaymentNotice|PaymentReconciliation|Permission|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RegulatedAuthorization|RelatedPerson|RequestOrchestration|Requirements|ResearchStudy|ResearchSubject|RiskAssessment|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|SubscriptionStatus|SubscriptionTopic|Substance|SubstanceDefinition|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestPlan|TestReport|TestScript|Transport|ValueSet|VerificationResult|VisionPrescription)\\\\/[A-Za-z0-9\\\\-\\\\.]{1,64}";
public final static String LOCAL_REF_REGEX = "(Account|ActivityDefinition|ActorDefinition|AdministrableProductDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|ArtifactAssessment|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BiologicallyDerivedProductDispense|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|ChargeItem|ChargeItemDefinition|Citation|Claim|ClaimResponse|ClinicalImpression|ClinicalUseDefinition|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|ConditionDefinition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceAssociation|DeviceDefinition|DeviceDispense|DeviceMetric|DeviceRequest|DeviceUsage|DiagnosticReport|DocumentReference|Encounter|EncounterHistory|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceReport|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|FormularyItem|GenomicStudy|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingSelection|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|Ingredient|InsurancePlan|InventoryItem|InventoryReport|Invoice|Library|Linkage|List|Location|ManufacturedItemDefinition|Measure|MeasureReport|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProductDefinition|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionIntake|NutritionOrder|NutritionProduct|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|PackagedProductDefinition|Parameters|Patient|PaymentNotice|PaymentReconciliation|Permission|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RegulatedAuthorization|RelatedPerson|RequestOrchestration|Requirements|ResearchStudy|ResearchSubject|RiskAssessment|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|SubscriptionStatus|SubscriptionTopic|Substance|SubstanceDefinition|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestPlan|TestReport|TestScript|Transport|ValueSet|VerificationResult|VisionPrescription)\\/[A-Za-z0-9\\-\\.]{1,64}";
public final static String NS_SYSTEM_TYPE = "http://hl7.org/fhirpath/System.";
public final static String VERSION = "5.0.0";

View File

@ -155,7 +155,7 @@ public class PEBuilder {
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);
}
/**
@ -342,6 +342,7 @@ public class PEBuilder {
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);
@ -359,9 +360,9 @@ public class PEBuilder {
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 (passElementPropsCheck(defn, inExtension) && !Utilities.existsInList(defn.getName(), omitList)) {
if (defn.getType().size() > 1) {
// DebugUtilities.breakpoint();
// Debug/Utilities.breakpoint();
i++;
} else {
String name = uniquefy(names, defn.getName());
@ -434,7 +435,10 @@ public class PEBuilder {
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");
@ -679,4 +683,8 @@ public class PEBuilder {
public boolean isResource(String name) {
return cu.isResource(name);
}
public ContextUtilities getContextUtilities() {
return cu;
}
}

View File

@ -41,6 +41,7 @@ import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.profilemodel.PEDefinition.PEDefinitionElementMode;
import org.hl7.fhir.utilities.Utilities;
@ -85,7 +86,7 @@ public abstract class PEDefinition {
this.name = name;
this.profile = profile;
this.definition = definition;
this.path = path == null ? name : ppath+"."+name;
this.path = ppath == null ? name : ppath+"."+name;
}
@ -393,6 +394,19 @@ public abstract class PEDefinition {
return false;
}
public ValueSet valueSet() {
if (definition.getBinding().hasValueSet()) {
return builder.getContext().fetchResource(ValueSet.class, definition.getBinding().getValueSet());
}
return null;
}
public PEBuilder getBuilder() {
return builder;
}
}

View File

@ -1,13 +1,34 @@
package org.hl7.fhir.r5.profilemodel;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ResourceFactory;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.DateType;
import org.hl7.fhir.r5.model.DateTimeType;
import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.utilities.Base64;
import org.hl7.fhir.utilities.Utilities;
public class TestInstanceGenerator {
@ -15,50 +36,160 @@ public class TestInstanceGenerator {
private IWorkerContext context;
private Map<String, String> data;
protected TestInstanceGenerator(IWorkerContext context) {
public TestInstanceGenerator(IWorkerContext context) {
super();
this.context = context;
}
public Resource generate(StructureDefinition profile) {
public byte[] generate(StructureDefinition profile, FhirFormat format) throws FHIRException, IOException {
PEBuilder builder = new PEBuilder(context, PEElementPropertiesPolicy.NONE, true);
PEDefinition definition = builder.buildPEDefinition(profile);
Resource res = ResourceFactory.createResource(definition.types().get(0).getType());
populateByProfile(res, definition);
Element element = Manager.build(context, profile);
res.getMeta().addProfile(definition.profile.getVersionedUrl());
return res;
populateByProfile(element, definition, 0);
ByteArrayOutputStream ba = new ByteArrayOutputStream();
Manager.compose(context, element, ba, format, OutputStyle.PRETTY, null);
return ba.toByteArray();
}
protected void populateByProfile(Base base, PEDefinition definition) {
protected void populateByProfile(Element element, PEDefinition definition, int level) {
if (definition.types().size() == 1) {
for (PEDefinition pe : definition.directChildren(true)) {
if (pe.hasFixedValue()) {
if (pe.definition().hasPattern()) {
base.setProperty(pe.schemaName(), pe.definition().getPattern());
} else {
base.setProperty(pe.schemaName(), pe.definition().getFixed());
}
} else if (!pe.isSlicer() && pe.max() == 1) {
for (int i = 0; i < pe.min(); i++) {
Base b = null;
if (pe.schemaName().endsWith("[x]")) {
if (pe.types().size() == 1) {
b = base.addChild(pe.schemaName().replace("[x]", Utilities.capitalize(pe.types().get(0).getType())));
}
} else if (!pe.isBaseList()) {
b = base.makeProperty(pe.schemaName().hashCode(), pe.schemaName());
} else {
b = base.addChild(pe.schemaName());
}
if (b != null) {
populateByProfile(b, pe);
}
}
if (pe.max() > 0 && (!isIgnoredElement(pe.definition().getBase().getPath()) || pe.hasFixedValue())) {
populateElement(element, pe, level);
}
}
}
}
private boolean isIgnoredElement(String path) {
return Utilities.existsInList(path, "Identifier.assigner", "Resource.meta", "DomainResource.text", "Resource.implicitRules");
}
public void populateElement(Element element, PEDefinition pe, int level) {
System.out.println(pe.path());
if (!pe.isSlicer() && isNonAbstractType(pe)) {
if (pe.hasFixedValue()) {
Element focus = element.addElement(pe.schemaName());
Base fv = pe.definition().hasPattern() ? pe.definition().getPattern() : pe.definition().getFixed();
if (fv.isPrimitive()) {
focus.setValue(fv.primitiveValue());
} else {
populateElementFromDataType(element, fv, null);
}
} else {
makeChildElement(element, pe, level);
}
}
}
private boolean isNonAbstractType(PEDefinition pe) {
for (PEType t : pe.types()) {
if (!pe.getBuilder().getContextUtilities().isAbstractType(t.getType())) {
return true;
}
}
return false;
}
public void makeChildElement(Element element, PEDefinition pe, int level) {
Element b = null;
if (pe.schemaName().endsWith("[x]")) {
if (pe.types().size() == 1) {
b = element.makeElement(pe.schemaName().replace("[x]", Utilities.capitalize(pe.types().get(0).getType())));
}
} else {
b = element.makeElement(pe.schemaName());
}
if (b != null) {
if (pe.definition.hasBinding()) {
ValueSet vs = pe.valueSet();
if (vs != null) {
ValueSetExpansionOutcome vse = context.expandVS(vs, true, false);
if (vse.isOk()) {
ValueSetExpansionContainsComponent cc = pickRandomConcept(vse.getValueset().getExpansion().getContains());
if (b.isPrimitive()) {
b.setValue(vse.getValueset().getExpansion().getContainsFirstRep().getCode());
} else if ("Coding".equals(b.fhirType())) {
populateElementFromDataType(b, new Coding(cc), null);
} else if ("CodeableConcept".equals(b.fhirType())) {
populateElementFromDataType(b, new CodeableConcept(new Coding(cc)), null);
}
} else {
System.out.println(" ValueSet Error: "+vse.getError());
}
} else {
System.out.println(" Unknown ValueSet: "+pe.definition.getBinding().getValueSet());
}
} else if (b.isPrimitive()) {
switch (b.fhirType()) {
case "id":
b.setValue(UUID.randomUUID().toString().toLowerCase());
break;
case "string":
b.setValue("Some String value");
break;
case "base64Binary" :
b.setValue(java.util.Base64.getMimeEncoder().encodeToString("Some Binary Value".getBytes(StandardCharsets.UTF_8)));
break;
case "boolean" :
b.setValue(ThreadLocalRandom.current().nextInt(0, 2) == 1 ? "true" : "false");
break;
case "date" :
b.setValue(new DateType(new Date()).asStringValue());
break;
case "dateTime":
b.setValue(new DateTimeType(new Date()).asStringValue());
break;
case "positiveInt" :
b.setValue(Integer.toString(ThreadLocalRandom.current().nextInt(1, 1000)));
break;
case "usignedInt" :
b.setValue(Integer.toString(ThreadLocalRandom.current().nextInt(0, 1000)));
break;
case "url" :
b.setValue("http://some.url/path");
break;
default:
System.out.println("Unhandled type: "+b.fhirType());
}
} else {
populateByProfile(b, pe, level+1);
}
}
}
private ValueSetExpansionContainsComponent pickRandomConcept(List<ValueSetExpansionContainsComponent> list) {
ValueSetExpansionContainsComponent res = null;
while (res == null) {
int r = ThreadLocalRandom.current().nextInt(0, list.size());
if (list.get(r).getAbstract()) {
if (list.get(r).hasContains()) {
res = pickRandomConcept(list.get(0).getContains());
}
} else {
res = list.get(r);
}
}
return res;
}
private void populateElementFromDataType(Element element, Base source, PEDefinition defn) {
for (Property prop : source.children()) {
for (Base b : prop.getValues()) {
Element child = element.makeElement(prop.getName());
if (b.isPrimitive()) {
child.setValue(b.primitiveValue());
} else {
populateElementFromDataType(child, b, null);
}
}
}
}
}

View File

@ -1046,30 +1046,32 @@ public class DataRenderer extends Renderer implements CodeResolver {
if (!renderPrimitiveWithNoValue(status, x, uri)) {
String v = uri.primitiveValue();
if (context.getContextUtilities().isResource(v)) {
v = "http://hl7.org/fhir/"+v;
}
if (v.startsWith("mailto:")) {
x.ah(v).addText(v.substring(7));
} else {
Resource r = context.getContext().fetchResource(Resource.class, v);
if (r != null && r.getWebPath() != null) {
if (r instanceof CanonicalResource) {
x.ah(context.prefixLocalHref(r.getWebPath())).addText(crPresent((CanonicalResource) r));
} else {
x.ah(context.prefixLocalHref(r.getWebPath())).addText(v);
}
if (v != null) {
if (context.getContextUtilities().isResource(v)) {
v = "http://hl7.org/fhir/"+v;
}
if (v.startsWith("mailto:")) {
x.ah(v).addText(v.substring(7));
} else {
String url = context.getResolver() != null ? context.getResolver().resolveUri(context, v) : null;
if (url != null) {
x.ah(context.prefixLocalHref(url)).addText(v);
} else if (Utilities.isAbsoluteUrlLinkable(v) && !uri.fhirType().equals("id")) {
x.ah(context.prefixLocalHref(v)).addText(v);
Resource r = context.getContext().fetchResource(Resource.class, v);
if (r != null && r.getWebPath() != null) {
if (r instanceof CanonicalResource) {
x.ah(context.prefixLocalHref(r.getWebPath())).addText(crPresent((CanonicalResource) r));
} else {
x.ah(context.prefixLocalHref(r.getWebPath())).addText(v);
}
} else {
x.addText(v);
String url = context.getResolver() != null ? context.getResolver().resolveUri(context, v) : null;
if (url != null) {
x.ah(context.prefixLocalHref(url)).addText(v);
} else if (Utilities.isAbsoluteUrlLinkable(v) && !uri.fhirType().equals("id")) {
x.ah(context.prefixLocalHref(v)).addText(v);
} else {
x.addText(v);
}
}
}
}
}
}
checkRenderExtensions(status, x, uri);
}

View File

@ -15,6 +15,7 @@ import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.r5.model.ContactDetail;
import org.hl7.fhir.r5.model.ContactPoint;
import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem;
@ -354,7 +355,7 @@ public abstract class ResourceRenderer extends DataRenderer {
ResourceWithReference rr = resolveReference(actual);
if (rr == null) {
String disp = display != null && display.hasPrimitiveValue() ? displayDataType(display) : actual.primitiveValue();
if (Utilities.isAbsoluteUrl(actual.primitiveValue()) || !context.isUnknownLocalReferencesNotLinks()) {
if (Utilities.isAbsoluteUrlLinkable(actual.primitiveValue()) || (isLocalReference(actual.primitiveValue()) && !context.isUnknownLocalReferencesNotLinks())) {
x.ah(context.prefixLocalHref(actual.primitiveValue())).tx(disp);
} else {
x.code().tx(disp);
@ -386,6 +387,21 @@ public abstract class ResourceRenderer extends DataRenderer {
}
private boolean isLocalReference(String url) {
if (url == null) {
return false;
}
if (url.contains("/_history")) {
url = url.substring(0, url.indexOf("/_hist"));
}
if (url.matches(Constants.LOCAL_REF_REGEX)) {
return true;
} else {
return false;
}
}
public void renderReference(ResourceWrapper res, HierarchicalTableGenerator gen, List<Piece> pieces, Reference r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
if (r == null) {
pieces.add(gen.new Piece(null, "null!", null));
@ -844,7 +860,7 @@ public abstract class ResourceRenderer extends DataRenderer {
}
protected XhtmlNode renderResourceTechDetails(ResourceWrapper r, XhtmlNode x) throws UnsupportedEncodingException, FHIRException, IOException {
return renderResourceTechDetails(r, x, (context.isContained() ? " #"+r.getId() : r.getId()));
return renderResourceTechDetails(r, x, (context.isContained() && r.getId() != null ? "#"+r.getId() : r.getId()));
}
protected XhtmlNode renderResourceTechDetails(ResourceWrapper r, XhtmlNode x, String desc) throws UnsupportedEncodingException, FHIRException, IOException {

View File

@ -40,7 +40,7 @@ class LanguageUtilsTest implements ResourceLoaderTests {
Writer generatedResource = new StringWriter();
jp.compose(element, new JsonCreatorDirect(generatedResource, false, false));
assert result == 3;
Assertions.assertEquals(3, result);
InputStream translatedResource = getResourceAsInputStream("languageUtils", "CodeSystem-answer-translated.json");
String text = new BufferedReader(new InputStreamReader(translatedResource))

View File

@ -1,6 +1,21 @@
package org.hl7.fhir.utilities;
import java.util.Comparator;
public class StringPair {
public static class Sorter implements Comparator<StringPair> {
@Override
public int compare(StringPair o1, StringPair o2) {
int res = o1.name.compareTo(o2.name);
if (res == 0) {
res = o1.value.compareTo(o2.value);
}
return res;
}
}
private String name;
private String value;

View File

@ -80,8 +80,8 @@ public class JsonLangFileProducer extends LanguageFileProducer {
JsonObject entry = new JsonObject();
json.forceArray("entries").add(entry);
entry.add("id", unit.getId());
if (unit.getContext1() != null) {
entry.add("context", unit.getContext1());
if (unit.getContext() != null) {
entry.add("context", unit.getContext());
}
entry.add("source", unit.getSrcText());
entry.add("target", unit.getTgtText());
@ -127,8 +127,8 @@ public class JsonLangFileProducer extends LanguageFileProducer {
JsonObject entry = new JsonObject();
lj.forceArray("entries").add(entry);
entry.add("id", tu.getId());
if (tu.getContext1() != null) {
entry.add("context", tu.getContext1());
if (tu.getContext() != null) {
entry.add("context", tu.getContext());
}
if (tu.getOriginal() != null) {
entry.add("original", tu.getOriginal());

View File

@ -40,7 +40,7 @@ public abstract class LanguageFileProducer {
* Additional language that helps establish the context
* @return
*/
public String getContext1() {
public String getContext() {
return context;
}

View File

@ -58,8 +58,16 @@ public class PoGetTextProducer extends LanguageFileProducer {
public POGetTextLanguageProducerLanguageSession(String id, String baseLang, String targetLang) {
super(id, baseLang, targetLang);
po = new StringBuilder();
ln("msgid \"\"");
ln("msgstr \"\"");
ln("\"Language: pt\\n\"");
ln("\"X-Generator: Poedit 3.5\\n\"");
ln("");
ln("# "+baseLang+" -> "+targetLang);
ln("");
ln("\"Language: pt\\n\"");
ln("");
}
protected void ln(String line) {
@ -74,10 +82,10 @@ public class PoGetTextProducer extends LanguageFileProducer {
@Override
public void entry(TextUnit unit) {
ln("#: "+unit.getId());
if (unit.getContext1() != null) {
ln("#. "+unit.getContext1());
if (unit.getContext() != null) {
ln("#. "+unit.getContext());
}
ln("msgctxt \""+unit.getId()+"\"");
ln("msgid \""+unit.getSrcText()+"\"");
ln("msgstr \""+(unit.getTgtText() == null ? "" : unit.getTgtText())+"\"");
ln("");
@ -160,16 +168,21 @@ public class PoGetTextProducer extends LanguageFileProducer {
@Override
public void produce(String id, String baseLang, String targetLang, List<TranslationUnit> translations, String filename) throws IOException {
StringBuilder po = new StringBuilder();
ln(po, "msgid \"\"");
ln(po, "msgstr \"\"");
ln(po, "\"Language: "+targetLang+"\\n\"");
ln(po, "\"X-Generator: Poedit 3.5\\n\"");
ln(po, "");
ln(po, "# "+baseLang+" -> "+targetLang);
ln(po, "");
for (TranslationUnit tu : translations) {
ln(po, "#: "+tu.getId());
if (tu.getContext1() != null) {
ln(po, "#. "+tu.getContext1());
if (tu.getContext() != null) {
ln(po, "#. "+tu.getContext());
}
if (tu.getOriginal() != null) {
ln(po, "#| "+tu.getOriginal());
}
ln(po, "msgctxt \""+tu.getId()+"\"");
ln(po, "msgid \""+stripEoln(tu.getSrcText())+"\"");
ln(po, "msgstr \""+(tu.getTgtText() == null ? "" : stripEoln(tu.getTgtText()))+"\"");
ln(po, "");

View File

@ -47,9 +47,9 @@ public class XLIFFProducer extends LanguageFileProducer {
public void entry(TextUnit unit) {
i++;
ln(" <trans-unit id=\""+id+"\" resname=\""+unit.getId()+"\">");
if (unit.getContext1() != null) {
if (unit.getContext() != null) {
ln(" <notes>");
ln(" <note id=\"n"+i+"\">"+Utilities.escapeXml(unit.getContext1())+"</note>");
ln(" <note id=\"n"+i+"\">"+Utilities.escapeXml(unit.getContext())+"</note>");
ln(" </notes>");
}
ln(" <source>"+Utilities.escapeXml(unit.getSrcText())+"</source>");
@ -149,10 +149,10 @@ public class XLIFFProducer extends LanguageFileProducer {
for (TranslationUnit tu : translations) {
int i = 0;
ln(xml, " <trans-unit id=\""+id+"\" resname=\""+tu.getId()+"\">");
if (tu.getContext1() != null) {
if (tu.getContext() != null) {
i++;
ln(xml, " <notes>");
ln(xml, " <note id=\"n"+i+"\">"+Utilities.escapeXml(tu.getContext1())+"</note>");
ln(xml, " <note id=\"n"+i+"\">"+Utilities.escapeXml(tu.getContext())+"</note>");
ln(xml, " </notes>");
}
ln(xml, " <source>"+Utilities.escapeXml(tu.getSrcText())+"</source>");

View File

@ -60,6 +60,7 @@ import org.apache.commons.compress.compressors.gzip.GzipParameters;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.ByteProvider;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.StringPair;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
@ -751,9 +752,17 @@ public class NpmPackage {
return listResources(Utilities.strings(types));
}
public List<String> listResourcesinFolder(String folder, String... types) throws IOException {
return listResourcesInFolder(folder, Utilities.strings(types));
}
public List<String> listResources(List<String> types) throws IOException {
return listResourcesInFolder("package", types);
}
public List<String> listResourcesInFolder(String folderName, List<String> types) throws IOException {
List<String> res = new ArrayList<String>();
NpmPackageFolder folder = folders.get("package");
NpmPackageFolder folder = folders.get(folderName);
if (types.size() == 0) {
for (String s : folder.types.keySet()) {
if (folder.types.containsKey(s)) {
@ -771,6 +780,31 @@ public class NpmPackage {
return res;
}
public List<StringPair> listAllResources(List<String> types) throws IOException {
List<StringPair> res = new ArrayList<StringPair>();
for (NpmPackageFolder folder : folders.values()) {
if (types.size() == 0) {
for (String s : folder.types.keySet()) {
if (folder.types.containsKey(s)) {
for (String n : folder.types.get(s)) {
res.add(new StringPair(folder.folderName, n));
}
}
}
} else {
for (String s : types) {
if (folder.types.containsKey(s)) {
for (String n : folder.types.get(s)) {
res.add(new StringPair(folder.folderName, n));
}
}
}
}
}
Collections.sort(res, new StringPair.Sorter());
return res;
}
public List<PackageResourceInformation> listIndexedResources(String... types) throws IOException {
return listIndexedResources(Utilities.strings(types));
}

View File

@ -176,6 +176,14 @@ public class PackageList {
setDate(date);
}
public List<String> languages() {
return json.forceArray("languages").asStrings();
}
public PackageListEntry addLang(String langCode) {
json.forceArray("languages").add(langCode);
return this;
}
}
private String source;

View File

@ -49,8 +49,8 @@ public class PackageServer {
public static final String PRIMARY_SERVER = "https://packages.fhir.org";
public static final String SECONDARY_SERVER = "https://packages2.fhir.org/packages";
public static final String SECONDARY_SERVER = "https://packages.fhir.org";
public static final String PRIMARY_SERVER = "https://packages2.fhir.org/packages";
public static PackageServer primaryServer() {
return new PackageServer(PRIMARY_SERVER);

View File

@ -506,7 +506,12 @@ public class JsonParserTests {
Assertions.assertEquals("-1.2e10", JsonParser.compose(e));
Assertions.assertEquals("// comment\n-1.2e10\n", JsonParser.compose(e, true));
}
@Test
public void testDecimal() throws IOException, JsonException {
JsonObject o = JsonParser.parseObject("{ \"n\" : 0.00001 }");
Assertions.assertEquals("0.00001", o.getJsonNumber("n").asString());
}
@Test
public void testElementString() throws IOException, JsonException {
JsonElement e = JsonParser.parse("\"str\\ning\"");

View File

@ -324,7 +324,7 @@ public class ValueSetValidator extends BaseValidator {
List<VSCodingValidationRequest> batch = new ArrayList<>();
boolean first = true;
if (concepts.size() > TOO_MANY_CODES_TO_VALIDATE) {
hint(errors, "2023-09-06", IssueType.BUSINESSRULE, stack, false, I18nConstants.VALUESET_INC_TOO_MANY_CODES, batch.size());
hint(errors, "2023-09-06", IssueType.BUSINESSRULE, stack, false, I18nConstants.VALUESET_INC_TOO_MANY_CODES, concepts.size());
} else {
if (((InstanceValidator) parent).isValidateValueSetCodesOnTxServer() && !context.isNoTerminologyServer()) {
try {

View File

@ -572,9 +572,9 @@ public class SnapShotGenerationXTests {
if (dst.exists())
dst.delete();
if (test.outputIsJson) {
XVersionLoader.saveJson(version, output, ManagedFileAccess.outStream(dst.getAbsolutePath()));
XVersionLoader.saveJson("5.0", output, ManagedFileAccess.outStream(dst.getAbsolutePath()));
} else {
XVersionLoader.saveXml(version, output, ManagedFileAccess.outStream(dst.getAbsolutePath()));
XVersionLoader.saveXml("5.0", output, ManagedFileAccess.outStream(dst.getAbsolutePath()));
}
if (test.outputIsJson) {
XVersionLoader.saveJson(version, test.expected, ManagedFileAccess.outStream(UtilitiesXTests.tempFile("snapshot", test.getId() + "-expected" + (test.outputIsJson ? ".json" : ".xml"))));

View File

@ -0,0 +1,32 @@
package org.hl7.fhir.generation.tests;
import java.io.IOException;
import org.hl7.fhir.convertors.loaders.loaderR5.NullLoaderKnowledgeProviderR5;
import org.hl7.fhir.convertors.loaders.loaderR5.R4ToR5Loader;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext.SimpleWorkerContextBuilder;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.profilemodel.TestInstanceGenerator;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.junit.jupiter.api.Test;
public class TestInstanceGenerationTester {
@Test
public void testBasic() throws IOException {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().build();
SimpleWorkerContext context = new SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).withDefaultParams().fromPackage(pcm.loadPackage("hl7.fhir.r4.core"));
context.loadFromPackage(pcm.loadPackage("us.nlm.vsac#0.21.0"), new R4ToR5Loader(Utilities.strings("CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"),
new NullLoaderKnowledgeProviderR5(), context.getVersion()));
context.loadFromPackage(pcm.loadPackage("hl7.fhir.us.core#6.0.0"), new R4ToR5Loader(Utilities.strings("CapabilityStatement", "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"),
new NullLoaderKnowledgeProviderR5(), context.getVersion()));
TestInstanceGenerator gen = new TestInstanceGenerator(context);
byte[] output = gen.generate(context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"), FhirFormat.JSON);
String res = new String(output);
System.out.println(res);
}
}

View File

@ -11179,7 +11179,6 @@ v: {
"error" : "Wrong Display Name 'O2 % BldC Oximetry' for http://loinc.org#59408-5. Valid display is one of 3 choices: 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US), 'Oxygen saturation in Arterial blood by Pulse oximetry' (en-US) or 'SaO2 % BldA PulseOx' (en-US) (for the language(s) 'en-US')",
"class" : "UNKNOWN",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome",
"issue" : [{
@ -11222,7 +11221,6 @@ v: {
"system" : "http://loinc.org",
"version" : "2.78",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome"
}
@ -11251,7 +11249,6 @@ v: {
"error" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8. Valid display is one of 4 choices: 'Inhaled oxygen flow rate' (en-US), 'Inhaled oxygen flow rate' (en-US), 'Inhaled O2 flow rate' (en-US) or 'Inhaled oxygen' (en-US) (for the language(s) 'en-US')",
"class" : "UNKNOWN",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome",
"issue" : [{
@ -11275,3 +11272,50 @@ v: {
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://loinc.org",
"code" : "18776-5",
"display" : "Plan of care note"
}, "valueSet" :null, "langs":"en-US", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Plan of care note",
"code" : "18776-5",
"system" : "http://loinc.org",
"version" : "2.78",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome"
}
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://loinc.org",
"code" : "18776-5"
}, "url": "http://hl7.org/fhir/ValueSet/doc-typecodes--0", "version": "4.0.1", "langs":"en-US", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Plan of care note",
"code" : "18776-5",
"system" : "http://loinc.org",
"version" : "2.78",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "",
"issues" : {
"resourceType" : "OperationOutcome"
}
}
-------------------------------------------------------------------------------------

View File

@ -23,7 +23,7 @@
<commons_io_version>2.17.0</commons_io_version>
<guava_version>32.0.1-jre</guava_version>
<hapi_fhir_version>6.4.1</hapi_fhir_version>
<validator_test_case_version>1.7.0</validator_test_case_version>
<validator_test_case_version>1.7.1-SNAPSHOT</validator_test_case_version>
<jackson_version>2.17.0</jackson_version>
<junit_jupiter_version>5.9.2</junit_jupiter_version>
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>