From b8370f7e61ec45e60b74c72d85a3e869d95f2a8a Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Sep 2020 06:17:45 +1000 Subject: [PATCH 1/2] various minor fixes (#353) * Ensure "I" flag in profile table representation is not used for underlying infrastructural constraints that exist everywhere * render multiple values for properties if they exist * fix for npe * fix for use of "current" as version * fix bad package URLs as they are loaded * RELEASE_NOTES.md --- RELEASE_NOTES.md | 9 +++++ .../fhir/r5/conformance/ProfileUtilities.java | 40 +++++++++++++++++-- .../fhir/r5/renderers/CodeSystemRenderer.java | 20 +++++----- .../hl7/fhir/r5/renderers/DataRenderer.java | 14 +++---- .../hl7/fhir/utilities/VersionUtilities.java | 4 ++ .../hl7/fhir/utilities/cache/NpmPackage.java | 2 +- 6 files changed, 68 insertions(+), 21 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e69de29bb..de602e213 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -0,0 +1,9 @@ +Validator: +* no changes with impact + +Other code changes: +* Ensure "I" flag in profile table representation is not used just for infrastructural constraints +* Render multiple values for properties in CodeSystems if they exist +* Fix for npe rendering resources based on profiles +* fix for use of "current" as version +* hack for past bad package URLs \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java index 970bac706..532fef47d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileUtilities.java @@ -3812,7 +3812,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (element != null && element.getIsSummary()) { checkForNoChange(element.getIsSummaryElement(), gc.addStyledText(translate("sd.table", "This element is included in summaries"), "\u03A3", null, null, null, false)); } - if (element != null && (!element.getConstraint().isEmpty() || !element.getCondition().isEmpty())) { + if (element != null && (hasNonBaseConstraints(element.getConstraint()) || hasNonBaseConditions(element.getCondition()))) { gc.addStyledText(translate("sd.table", "This element has or is affected by some invariants ("+listConstraintsAndConditions(element)+")"), "I", null, null, null, false); } @@ -3860,7 +3860,8 @@ public class ProfileUtilities extends TranslatingUtilities { return res; } - private Cell addCell(Row row, Cell cell) { + + private Cell addCell(Row row, Cell cell) { row.getCells().add(cell); return (cell); } @@ -3869,18 +3870,49 @@ public class ProfileUtilities extends TranslatingUtilities { return app == null ? src : src + app; } + private boolean hasNonBaseConditions(List conditions) { + for (IdType c : conditions) { + if (!isBaseCondition(c)) { + return true; + } + } + return false; + } + + + private boolean hasNonBaseConstraints(List constraints) { + for (ElementDefinitionConstraintComponent c : constraints) { + if (!isBaseConstraint(c)) { + return true; + } + } + return false; + } private String listConstraintsAndConditions(ElementDefinition element) { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); for (ElementDefinitionConstraintComponent con : element.getConstraint()) { - b.append(con.getKey()); + if (!isBaseConstraint(con)) { + b.append(con.getKey()); + } } for (IdType id : element.getCondition()) { - b.append(id.asStringValue()); + if (!isBaseCondition(id)) { + b.append(id.asStringValue()); + } } return b.toString(); } + private boolean isBaseCondition(IdType c) { + String key = c.asStringValue(); + return key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-"); + } + + private boolean isBaseConstraint(ElementDefinitionConstraintComponent con) { + String key = con.getKey(); + return key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-"); + } private void makeChoiceRows(List subRows, ElementDefinition element, HierarchicalTableGenerator gen, String corePath, String profileBaseFileName) { // create a child for each choice diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java index 028b2c68a..7af63b922 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/CodeSystemRenderer.java @@ -416,15 +416,17 @@ public class CodeSystemRenderer extends TerminologyRenderer { for (PropertyComponent pc : properties) { td = tr.td(); boolean first = true; - ConceptPropertyComponent pcv = CodeSystemUtilities.getProperty(c, pc.getCode()); - if (pcv != null && pcv.hasValue()) { - if (first) first = false; else td.addText(", "); - if (pcv.hasValueCoding()) { - td.addText(pcv.getValueCoding().getCode()); - } else if (pcv.hasValueStringType() && Utilities.isAbsoluteUrl(pcv.getValue().primitiveValue())) { - td.ah(pcv.getValue().primitiveValue()).tx(pcv.getValue().primitiveValue()); - } else { - td.addText(pcv.getValue().primitiveValue()); + List pcvl = CodeSystemUtilities.getPropertyValues(c, pc.getCode()); + for (ConceptPropertyComponent pcv : pcvl) { + if (pcv.hasValue()) { + if (first) first = false; else td.addText(", "); + if (pcv.hasValueCoding()) { + td.addText(pcv.getValueCoding().getCode()); + } else if (pcv.hasValueStringType() && Utilities.isAbsoluteUrl(pcv.getValue().primitiveValue())) { + td.ah(pcv.getValue().primitiveValue()).tx(pcv.getValue().primitiveValue()); + } else { + td.addText(pcv.getValue().primitiveValue()); + } } } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java index ac04d007d..2033956f9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java @@ -251,12 +251,12 @@ public class DataRenderer extends Renderer { } else { return "No display for "+b.fhirType(); } - } public String display(DataType type) { - if (type.isEmpty()) + if (type == null || type.isEmpty()) { return ""; + } if (type instanceof Coding) { return displayCoding((Coding) type); @@ -354,7 +354,6 @@ public class DataRenderer extends Renderer { } else { x.tx("No display for "+type.fhirType()); } - } private void renderReference(XhtmlNode x, Reference ref) { @@ -368,15 +367,17 @@ public class DataRenderer extends Renderer { } public void renderDateTime(XhtmlNode x, Base e) { - if (e.hasPrimitiveValue()) + if (e.hasPrimitiveValue()) { x.addText(((DateTimeType) e).toHumanDisplay()); + } } protected void renderUri(XhtmlNode x, UriType uri) { - if (uri.getValue().startsWith("mailto:")) + if (uri.getValue().startsWith("mailto:")) { x.ah(uri.getValue()).addText(uri.getValue().substring(7)); - else + } else { x.ah(uri.getValue()).addText(uri.getValue()); + } } protected void renderUri(XhtmlNode x, UriType uri, String path, String id) { @@ -782,7 +783,6 @@ public class DataRenderer extends Renderer { } } - protected String displayQuantity(Quantity q) { StringBuilder s = new StringBuilder(); diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java index c90530f2a..83e69ed40 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java @@ -181,6 +181,10 @@ public class VersionUtilities { public static String getMajMin(String version) { if (version == null) return null; + + if ("current".equals(version)) { + return CURRENT_VERSION; + } if (Utilities.charCount(version, '.') == 1) { String[] p = version.split("\\."); diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/cache/NpmPackage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/cache/NpmPackage.java index b87b60818..f32ef1380 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/cache/NpmPackage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/cache/NpmPackage.java @@ -814,7 +814,7 @@ public class NpmPackage { public String getWebLocation() { if (npm.has("url")) { - return npm.get("url").getAsString(); + return PackageHacker.fixPackageUrl(npm.get("url").getAsString()); } else { return JSONUtil.str(npm, "canonical"); } From 8eeffb89795b86a126cfeb6f3623dcb4070b0623 Mon Sep 17 00:00:00 2001 From: Mark Iantorno Date: Wed, 23 Sep 2020 07:01:24 -0400 Subject: [PATCH 2/2] fixed conversion for Device (#355) --- .../convertors/VersionConvertor_30_40.java | 87 +----- .../convertors/conv30_40/Device30_40.java | 258 ++++++++++++++++++ .../convertors/conv30_40/Device30_40Test.java | 43 +++ .../src/test/resources/0_device_30.json | 13 + .../src/test/resources/0_device_40.json | 20 ++ .../src/test/resources/1_device_30.json | 13 + .../src/test/resources/1_device_40.json | 20 ++ 7 files changed, 370 insertions(+), 84 deletions(-) create mode 100644 org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_40/Device30_40.java create mode 100644 org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/conv30_40/Device30_40Test.java create mode 100644 org.hl7.fhir.convertors/src/test/resources/0_device_30.json create mode 100644 org.hl7.fhir.convertors/src/test/resources/0_device_40.json create mode 100644 org.hl7.fhir.convertors/src/test/resources/1_device_30.json create mode 100644 org.hl7.fhir.convertors/src/test/resources/1_device_40.json diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_40.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_40.java index 4837eeb0f..af922aba6 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_40.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_30_40.java @@ -4,90 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.hl7.fhir.convertors.conv30_40.Account30_40; -import org.hl7.fhir.convertors.conv30_40.ActivityDefinition30_40; -import org.hl7.fhir.convertors.conv30_40.AllergyIntolerance30_40; -import org.hl7.fhir.convertors.conv30_40.Appointment30_40; -import org.hl7.fhir.convertors.conv30_40.AppointmentResponse30_40; -import org.hl7.fhir.convertors.conv30_40.AuditEvent30_40; -import org.hl7.fhir.convertors.conv30_40.Basic30_40; -import org.hl7.fhir.convertors.conv30_40.Binary30_40; -import org.hl7.fhir.convertors.conv30_40.BodySite30_40; -import org.hl7.fhir.convertors.conv30_40.Bundle30_40; -import org.hl7.fhir.convertors.conv30_40.CapabilityStatement30_40; -import org.hl7.fhir.convertors.conv30_40.CarePlan30_40; -import org.hl7.fhir.convertors.conv30_40.CareTeam30_40; -import org.hl7.fhir.convertors.conv30_40.ClinicalImpression30_40; -import org.hl7.fhir.convertors.conv30_40.CodeSystem30_40; -import org.hl7.fhir.convertors.conv30_40.Communication30_40; -import org.hl7.fhir.convertors.conv30_40.CompartmentDefinition30_40; -import org.hl7.fhir.convertors.conv30_40.Composition30_40; -import org.hl7.fhir.convertors.conv30_40.ConceptMap30_40; -import org.hl7.fhir.convertors.conv30_40.Condition30_40; -import org.hl7.fhir.convertors.conv30_40.Consent30_40; -import org.hl7.fhir.convertors.conv30_40.Coverage30_40; -import org.hl7.fhir.convertors.conv30_40.DataElement30_40; -import org.hl7.fhir.convertors.conv30_40.DetectedIssue30_40; -import org.hl7.fhir.convertors.conv30_40.DeviceUseStatement30_40; -import org.hl7.fhir.convertors.conv30_40.DiagnosticReport30_40; -import org.hl7.fhir.convertors.conv30_40.DocumentReference30_40; -import org.hl7.fhir.convertors.conv30_40.Encounter30_40; -import org.hl7.fhir.convertors.conv30_40.Endpoint30_40; -import org.hl7.fhir.convertors.conv30_40.EpisodeOfCare30_40; -import org.hl7.fhir.convertors.conv30_40.ExpansionProfile30_40; -import org.hl7.fhir.convertors.conv30_40.FamilyMemberHistory30_40; -import org.hl7.fhir.convertors.conv30_40.Flag30_40; -import org.hl7.fhir.convertors.conv30_40.Goal30_40; -import org.hl7.fhir.convertors.conv30_40.GraphDefinition30_40; -import org.hl7.fhir.convertors.conv30_40.Group30_40; -import org.hl7.fhir.convertors.conv30_40.HealthcareService30_40; -import org.hl7.fhir.convertors.conv30_40.ImagingStudy30_40; -import org.hl7.fhir.convertors.conv30_40.Immunization30_40; -import org.hl7.fhir.convertors.conv30_40.ImplementationGuide30_40; -import org.hl7.fhir.convertors.conv30_40.Library30_40; -import org.hl7.fhir.convertors.conv30_40.Linkage30_40; -import org.hl7.fhir.convertors.conv30_40.List30_40; -import org.hl7.fhir.convertors.conv30_40.Location30_40; -import org.hl7.fhir.convertors.conv30_40.Media30_40; -import org.hl7.fhir.convertors.conv30_40.Medication30_40; -import org.hl7.fhir.convertors.conv30_40.MedicationAdministration30_40; -import org.hl7.fhir.convertors.conv30_40.MedicationDispense30_40; -import org.hl7.fhir.convertors.conv30_40.MedicationRequest30_40; -import org.hl7.fhir.convertors.conv30_40.MedicationStatement30_40; -import org.hl7.fhir.convertors.conv30_40.MessageDefinition30_40; -import org.hl7.fhir.convertors.conv30_40.MessageHeader30_40; -import org.hl7.fhir.convertors.conv30_40.NamingSystem30_40; -import org.hl7.fhir.convertors.conv30_40.Observation30_40; -import org.hl7.fhir.convertors.conv30_40.OperationDefinition30_40; -import org.hl7.fhir.convertors.conv30_40.OperationOutcome30_40; -import org.hl7.fhir.convertors.conv30_40.Organization30_40; -import org.hl7.fhir.convertors.conv30_40.Parameters30_40; -import org.hl7.fhir.convertors.conv30_40.Patient30_40; -import org.hl7.fhir.convertors.conv30_40.PaymentNotice30_40; -import org.hl7.fhir.convertors.conv30_40.Person30_40; -import org.hl7.fhir.convertors.conv30_40.PlanDefinition30_40; -import org.hl7.fhir.convertors.conv30_40.Practitioner30_40; -import org.hl7.fhir.convertors.conv30_40.PractitionerRole30_40; -import org.hl7.fhir.convertors.conv30_40.Procedure30_40; -import org.hl7.fhir.convertors.conv30_40.ProcedureRequest30_40; -import org.hl7.fhir.convertors.conv30_40.Provenance30_40; -import org.hl7.fhir.convertors.conv30_40.Questionnaire30_40; -import org.hl7.fhir.convertors.conv30_40.QuestionnaireResponse30_40; -import org.hl7.fhir.convertors.conv30_40.RelatedPerson30_40; -import org.hl7.fhir.convertors.conv30_40.RiskAssessment30_40; -import org.hl7.fhir.convertors.conv30_40.Schedule30_40; -import org.hl7.fhir.convertors.conv30_40.SearchParameter30_40; -import org.hl7.fhir.convertors.conv30_40.Sequence30_40; -import org.hl7.fhir.convertors.conv30_40.Slot30_40; -import org.hl7.fhir.convertors.conv30_40.Specimen30_40; -import org.hl7.fhir.convertors.conv30_40.StructureDefinition30_40; -import org.hl7.fhir.convertors.conv30_40.StructureMap30_40; -import org.hl7.fhir.convertors.conv30_40.Subscription30_40; -import org.hl7.fhir.convertors.conv30_40.Substance30_40; -import org.hl7.fhir.convertors.conv30_40.SupplyDelivery30_40; -import org.hl7.fhir.convertors.conv30_40.TestReport30_40; -import org.hl7.fhir.convertors.conv30_40.TestScript30_40; -import org.hl7.fhir.convertors.conv30_40.ValueSet30_40; +import org.hl7.fhir.convertors.conv30_40.*; import org.hl7.fhir.dstu3.model.Parameters; import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent; import org.hl7.fhir.exceptions.FHIRException; @@ -5164,6 +5081,8 @@ public class VersionConvertor_30_40 { return Coverage30_40.convertCoverage((org.hl7.fhir.r4.model.Coverage) src); if (src instanceof org.hl7.fhir.r4.model.DetectedIssue) return DetectedIssue30_40.convertDetectedIssue((org.hl7.fhir.r4.model.DetectedIssue) src); + if (src instanceof org.hl7.fhir.r4.model.Device) + return Device30_40.convertDevice((org.hl7.fhir.r4.model.Device) src); if (src instanceof org.hl7.fhir.r4.model.DeviceUseStatement) return DeviceUseStatement30_40.convertDeviceUseStatement((org.hl7.fhir.r4.model.DeviceUseStatement) src); if (src instanceof org.hl7.fhir.r4.model.DiagnosticReport) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_40/Device30_40.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_40/Device30_40.java new file mode 100644 index 000000000..4e77bec9b --- /dev/null +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_40/Device30_40.java @@ -0,0 +1,258 @@ +package org.hl7.fhir.convertors.conv30_40; + + +import org.hl7.fhir.convertors.VersionConvertor_30_40; +import org.hl7.fhir.dstu3.model.Device; +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r4.model.Patient; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/* + Copyright (c) 2011+, HL7, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of HL7 nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*/ +// Generated on Sun, Feb 24, 2019 11:37+1100 for FHIR v4.0.0 +public class Device30_40 extends VersionConvertor_30_40 { + + public static org.hl7.fhir.r4.model.Device convertDevice(org.hl7.fhir.dstu3.model.Device src) throws FHIRException { + if (src == null) + return null; + org.hl7.fhir.r4.model.Device tgt = new org.hl7.fhir.r4.model.Device(); + copyDomainResource(src, tgt); + for (org.hl7.fhir.dstu3.model.Identifier t : src.getIdentifier()) tgt.addIdentifier(convertIdentifier(t)); + if (src.hasUdi()) { + org.hl7.fhir.r4.model.Device.DeviceUdiCarrierComponent carrierComponent = tgt.getUdiCarrierFirstRep(); + carrierComponent.setDeviceIdentifierElement(VersionConvertor_30_40.convertString(src.getUdi().getDeviceIdentifierElement())); + carrierComponent.setJurisdictionElement(VersionConvertor_30_40.convertUri(src.getUdi().getJurisdictionElement())); + carrierComponent.setCarrierHRFElement(VersionConvertor_30_40.convertString(src.getUdi().getCarrierHRFElement())); + carrierComponent.setCarrierAIDCElement(VersionConvertor_30_40.convertBase64Binary(src.getUdi().getCarrierAIDCElement())); + carrierComponent.setIssuerElement(VersionConvertor_30_40.convertUri(src.getUdi().getIssuerElement())); + carrierComponent.setEntryTypeElement(convertUDIEntryType(src.getUdi().getEntryTypeElement())); + tgt.setUdiCarrier(Collections.singletonList(carrierComponent)); + org.hl7.fhir.r4.model.Device.DeviceDeviceNameComponent nameComponent = tgt.getDeviceNameFirstRep(); + nameComponent.setNameElement(VersionConvertor_30_40.convertString(src.getUdi().getNameElement())); + nameComponent.setType(org.hl7.fhir.r4.model.Device.DeviceNameType.UDILABELNAME); + } + if (src.hasStatus()) + tgt.setStatusElement(convertFHIRDeviceStatus(src.getStatusElement())); + if (src.hasType()) + tgt.setType(convertCodeableConcept(src.getType())); + if (src.hasLotNumber()) + tgt.setLotNumberElement(convertString(src.getLotNumberElement())); + if (src.hasManufacturer()) + tgt.setManufacturerElement(convertString(src.getManufacturerElement())); + if (src.hasManufactureDate()) + tgt.setManufactureDateElement(convertDateTime(src.getManufactureDateElement())); + if (src.hasExpirationDate()) + tgt.setExpirationDateElement(convertDateTime(src.getExpirationDateElement())); + if (src.hasModelElement()) + tgt.setModelNumberElement(VersionConvertor_30_40.convertString(src.getModelElement())); + if (src.hasVersionElement()) + tgt.setVersion(Collections.singletonList(tgt.getVersionFirstRep().setValueElement(VersionConvertor_30_40.convertString(src.getVersionElement())))); + if (src.hasPatient()) + tgt.setPatient(convertReference(src.getPatient())); + if (src.hasOwner()) + tgt.setOwner(convertReference(src.getOwner())); + if (src.hasContact()) + tgt.setContact(src.getContact().stream().map(VersionConvertor_30_40::convertContactPoint).collect(Collectors.toList())); + if (src.hasLocation()) + tgt.setLocation(convertReference(src.getLocation())); + if (src.hasUrl()) + tgt.setUrlElement(convertUri(src.getUrlElement())); + for (org.hl7.fhir.dstu3.model.Annotation t : src.getNote()) tgt.addNote(convertAnnotation(t)); + for (org.hl7.fhir.dstu3.model.CodeableConcept t : src.getSafety()) tgt.addSafety(convertCodeableConcept(t)); + return tgt; + } + + public static org.hl7.fhir.dstu3.model.Device convertDevice(org.hl7.fhir.r4.model.Device src) throws FHIRException { + if (src == null) + return null; + org.hl7.fhir.dstu3.model.Device tgt = new org.hl7.fhir.dstu3.model.Device(); + copyDomainResource(src, tgt); + for (org.hl7.fhir.r4.model.Identifier t : src.getIdentifier()) tgt.addIdentifier(convertIdentifier(t)); + if (src.hasUdiCarrier()) { + Device.DeviceUdiComponent udi = tgt.getUdi(); + udi.setDeviceIdentifierElement(VersionConvertor_30_40.convertString(src.getUdiCarrierFirstRep().getDeviceIdentifierElement())); + udi.setJurisdictionElement(VersionConvertor_30_40.convertUri(src.getUdiCarrierFirstRep().getJurisdictionElement())); + udi.setCarrierHRFElement(VersionConvertor_30_40.convertString(src.getUdiCarrierFirstRep().getCarrierHRFElement())); + udi.setCarrierAIDCElement(VersionConvertor_30_40.convertBase64Binary(src.getUdiCarrierFirstRep().getCarrierAIDCElement())); + udi.setIssuerElement(VersionConvertor_30_40.convertUri(src.getUdiCarrierFirstRep().getIssuerElement())); + udi.setEntryTypeElement(convertUDIEntryType(src.getUdiCarrierFirstRep().getEntryTypeElement())); + tgt.setUdi(udi); + } + if (src.hasStatus()) + tgt.setStatusElement(convertFHIRDeviceStatus(src.getStatusElement())); + if (src.hasType()) + tgt.setType(convertCodeableConcept(src.getType())); + if (src.hasLotNumber()) + tgt.setLotNumberElement(convertString(src.getLotNumberElement())); + if (src.hasManufacturer()) + tgt.setManufacturerElement(convertString(src.getManufacturerElement())); + if (src.hasManufactureDate()) + tgt.setManufactureDateElement(convertDateTime(src.getManufactureDateElement())); + if (src.hasExpirationDate()) + tgt.setExpirationDateElement(convertDateTime(src.getExpirationDateElement())); + if (src.hasModelNumber()) + tgt.setModel(src.getModelNumber()); + if (src.hasVersion()) + tgt.setVersionElement(VersionConvertor_30_40.convertString(src.getVersion().get(0).getValueElement())); + if (src.hasDeviceName()) + tgt.setUdi(tgt.getUdi().setName(src.getDeviceName().get(0).getName())); + if (src.hasPatient()) + tgt.setPatient(convertReference(src.getPatient())); + if (src.hasOwner()) + tgt.setOwner(convertReference(src.getOwner())); + if (src.hasContact()) + tgt.setContact(src.getContact().stream().map(VersionConvertor_30_40::convertContactPoint).collect(Collectors.toList())); + if (src.hasLocation()) + tgt.setLocation(convertReference(src.getLocation())); + for (org.hl7.fhir.r4.model.ContactPoint t : src.getContact()) tgt.addContact(convertContactPoint(t)); + if (src.hasLocation()) + tgt.setLocation(VersionConvertor_30_40.convertReference(src.getLocation())); + if (src.hasUrl()) + tgt.setUrlElement(convertUri(src.getUrlElement())); + for (org.hl7.fhir.r4.model.Annotation t : src.getNote()) tgt.addNote(convertAnnotation(t)); + for (org.hl7.fhir.r4.model.CodeableConcept t : src.getSafety()) tgt.addSafety(convertCodeableConcept(t)); + return tgt; + } + + static public org.hl7.fhir.r4.model.Enumeration convertFHIRDeviceStatus(org.hl7.fhir.dstu3.model.Enumeration src) throws FHIRException { + if (src == null || src.isEmpty()) + return null; + org.hl7.fhir.r4.model.Enumeration tgt = new org.hl7.fhir.r4.model.Enumeration<>(new org.hl7.fhir.r4.model.Device.FHIRDeviceStatusEnumFactory()); + VersionConvertor_30_40.copyElement(src, tgt); + switch (src.getValue()) { + case ACTIVE: + tgt.setValue(org.hl7.fhir.r4.model.Device.FHIRDeviceStatus.ACTIVE); + break; + case INACTIVE: + tgt.setValue(org.hl7.fhir.r4.model.Device.FHIRDeviceStatus.INACTIVE); + break; + case ENTEREDINERROR: + tgt.setValue(org.hl7.fhir.r4.model.Device.FHIRDeviceStatus.ENTEREDINERROR); + break; + case UNKNOWN: + tgt.setValue(org.hl7.fhir.r4.model.Device.FHIRDeviceStatus.UNKNOWN); + break; + default: + tgt.setValue(org.hl7.fhir.r4.model.Device.FHIRDeviceStatus.NULL); + break; + } + return tgt; + } + + static public org.hl7.fhir.dstu3.model.Enumeration convertFHIRDeviceStatus(org.hl7.fhir.r4.model.Enumeration src) throws FHIRException { + if (src == null || src.isEmpty()) + return null; + org.hl7.fhir.dstu3.model.Enumeration tgt = new org.hl7.fhir.dstu3.model.Enumeration<>(new org.hl7.fhir.dstu3.model.Device.FHIRDeviceStatusEnumFactory()); + VersionConvertor_30_40.copyElement(src, tgt); + switch (src.getValue()) { + case ACTIVE: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.FHIRDeviceStatus.ACTIVE); + break; + case INACTIVE: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.FHIRDeviceStatus.INACTIVE); + break; + case ENTEREDINERROR: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.FHIRDeviceStatus.ENTEREDINERROR); + break; + case UNKNOWN: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.FHIRDeviceStatus.UNKNOWN); + break; + default: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.FHIRDeviceStatus.NULL); + break; + } + return tgt; + } + + static public org.hl7.fhir.r4.model.Enumeration convertUDIEntryType(org.hl7.fhir.dstu3.model.Enumeration src) throws FHIRException { + if (src == null || src.isEmpty()) + return null; + org.hl7.fhir.r4.model.Enumeration tgt = new org.hl7.fhir.r4.model.Enumeration<>(new org.hl7.fhir.r4.model.Device.UDIEntryTypeEnumFactory()); + VersionConvertor_30_40.copyElement(src, tgt); + switch (src.getValue()) { + case BARCODE: + tgt.setValue(org.hl7.fhir.r4.model.Device.UDIEntryType.BARCODE); + break; + case RFID: + tgt.setValue(org.hl7.fhir.r4.model.Device.UDIEntryType.RFID); + break; + case MANUAL: + tgt.setValue(org.hl7.fhir.r4.model.Device.UDIEntryType.MANUAL); + break; + case CARD: + tgt.setValue(org.hl7.fhir.r4.model.Device.UDIEntryType.CARD); + break; + case SELFREPORTED: + tgt.setValue(org.hl7.fhir.r4.model.Device.UDIEntryType.SELFREPORTED); + break; + case UNKNOWN: + tgt.setValue(org.hl7.fhir.r4.model.Device.UDIEntryType.UNKNOWN); + break; + default: + tgt.setValue(org.hl7.fhir.r4.model.Device.UDIEntryType.NULL); + break; + } + return tgt; + } + + static public org.hl7.fhir.dstu3.model.Enumeration convertUDIEntryType(org.hl7.fhir.r4.model.Enumeration src) throws FHIRException { + if (src == null || src.isEmpty()) + return null; + org.hl7.fhir.dstu3.model.Enumeration tgt = new org.hl7.fhir.dstu3.model.Enumeration<>(new org.hl7.fhir.dstu3.model.Device.UDIEntryTypeEnumFactory()); + VersionConvertor_30_40.copyElement(src, tgt); + switch (src.getValue()) { + case BARCODE: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.UDIEntryType.BARCODE); + break; + case RFID: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.UDIEntryType.RFID); + break; + case MANUAL: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.UDIEntryType.MANUAL); + break; + case CARD: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.UDIEntryType.CARD); + break; + case SELFREPORTED: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.UDIEntryType.SELFREPORTED); + break; + case UNKNOWN: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.UDIEntryType.UNKNOWN); + break; + default: + tgt.setValue(org.hl7.fhir.dstu3.model.Device.UDIEntryType.NULL); + break; + } + return tgt; + } +} \ No newline at end of file diff --git a/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/conv30_40/Device30_40Test.java b/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/conv30_40/Device30_40Test.java new file mode 100644 index 000000000..aa617a1e9 --- /dev/null +++ b/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/conv30_40/Device30_40Test.java @@ -0,0 +1,43 @@ +package org.hl7.fhir.convertors.conv30_40; + +import org.hl7.fhir.convertors.VersionConvertor_30_40; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; + +public class Device30_40Test { + @Test + @DisplayName("Test r4 -> dstu3 device conversion.") + public void test1() throws IOException { + InputStream r4_input = this.getClass().getResourceAsStream("/0_device_40.json"); + InputStream dstu3_expected_output = this.getClass().getResourceAsStream("/0_device_30.json"); + + org.hl7.fhir.r4.model.Device r4_actual = (org.hl7.fhir.r4.model.Device) new org.hl7.fhir.r4.formats.JsonParser().parse(r4_input); + org.hl7.fhir.dstu3.model.Resource dstu3_conv = VersionConvertor_30_40.convertResource(r4_actual, true); + + org.hl7.fhir.dstu3.formats.JsonParser dstu3_parser = new org.hl7.fhir.dstu3.formats.JsonParser(); + org.hl7.fhir.dstu3.model.Resource dstu3_expected = dstu3_parser.parse(dstu3_expected_output); + + Assertions.assertTrue(dstu3_expected.equalsDeep(dstu3_conv), + "Failed comparing\n" + dstu3_parser.composeString(dstu3_expected) + "\nand\n" + dstu3_parser.composeString(dstu3_conv)); + } + + @Test + @DisplayName("Test r4 -> dstu3 device conversion, part 2.") + public void test2() throws IOException { + InputStream r4_input = this.getClass().getResourceAsStream("/1_device_40.json"); + InputStream dstu3_expected_output = this.getClass().getResourceAsStream("/1_device_30.json"); + + org.hl7.fhir.r4.model.Device r4_actual = (org.hl7.fhir.r4.model.Device) new org.hl7.fhir.r4.formats.JsonParser().parse(r4_input); + org.hl7.fhir.dstu3.model.Resource dstu3_conv = VersionConvertor_30_40.convertResource(r4_actual, true); + + org.hl7.fhir.dstu3.formats.JsonParser dstu3_parser = new org.hl7.fhir.dstu3.formats.JsonParser(); + org.hl7.fhir.dstu3.model.Resource dstu3_expected = dstu3_parser.parse(dstu3_expected_output); + + Assertions.assertTrue(dstu3_expected.equalsDeep(dstu3_conv), + "Failed comparing\n" + dstu3_parser.composeString(dstu3_expected) + "\nand\n" + dstu3_parser.composeString(dstu3_expected)); + } +} \ No newline at end of file diff --git a/org.hl7.fhir.convertors/src/test/resources/0_device_30.json b/org.hl7.fhir.convertors/src/test/resources/0_device_30.json new file mode 100644 index 000000000..95555f10d --- /dev/null +++ b/org.hl7.fhir.convertors/src/test/resources/0_device_30.json @@ -0,0 +1,13 @@ +{ + "resourceType": "Device", + "id": "DEV000000000872", + "identifier": [ + { + "system": "https://fresenius.org/device", + "value": "DEV000000000872" + } + ], + "udi": { + "name": "LC021691" + } +} diff --git a/org.hl7.fhir.convertors/src/test/resources/0_device_40.json b/org.hl7.fhir.convertors/src/test/resources/0_device_40.json new file mode 100644 index 000000000..6d3895d27 --- /dev/null +++ b/org.hl7.fhir.convertors/src/test/resources/0_device_40.json @@ -0,0 +1,20 @@ +{ + "resourceType": "Device", + "id": "DEV000000000872", + "identifier": [ + { + "system": "https://fresenius.org/device", + "value": "DEV000000000872" + } + ], + "definition": { + "reference": "Dialysis" + }, + "serialNumber": "LC021691", + "deviceName": [ + { + "name": "LC021691", + "type": "manufacturer-name" + } + ] +} \ No newline at end of file diff --git a/org.hl7.fhir.convertors/src/test/resources/1_device_30.json b/org.hl7.fhir.convertors/src/test/resources/1_device_30.json new file mode 100644 index 000000000..e06402f5a --- /dev/null +++ b/org.hl7.fhir.convertors/src/test/resources/1_device_30.json @@ -0,0 +1,13 @@ +{ + "resourceType": "Device", + "id": "DEV000000000873", + "identifier": [ + { + "system": "https://fresenius.org/device", + "value": "DEV000000000873" + } + ], + "udi": { + "name": "LC020678" + } +} \ No newline at end of file diff --git a/org.hl7.fhir.convertors/src/test/resources/1_device_40.json b/org.hl7.fhir.convertors/src/test/resources/1_device_40.json new file mode 100644 index 000000000..d7bef3a9b --- /dev/null +++ b/org.hl7.fhir.convertors/src/test/resources/1_device_40.json @@ -0,0 +1,20 @@ +{ + "resourceType": "Device", + "id": "DEV000000000873", + "identifier": [ + { + "system": "https://fresenius.org/device", + "value": "DEV000000000873" + } + ], + "definition": { + "reference": "Dialysis" + }, + "serialNumber": "LC020678", + "deviceName": [ + { + "name": "LC020678", + "type": "manufacturer-name" + } + ] +} \ No newline at end of file