From 3d7f701b00295b150c3a2aa7a308e371aa9f5ae4 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 23 Aug 2019 14:57:05 +1000 Subject: [PATCH] update for changes to representation of special elements --- .../convertors/SpecDifferenceEvaluator.java | 30 +++---- .../convertors/VersionConvertor_40_50.java | 5 ++ .../fhir/r5/conformance/ProfileComparer.java | 4 +- .../fhir/r5/conformance/ShExGenerator.java | 28 +++--- .../r5/conformance/XmlSchemaGenerator.java | 21 ++--- .../hl7/fhir/r5/elementmodel/JsonParser.java | 36 ++++---- .../hl7/fhir/r5/elementmodel/Property.java | 24 ++--- .../java/org/hl7/fhir/r5/model/Constants.java | 2 + .../hl7/fhir/r5/model/ElementDefinition.java | 45 ++++++++++ .../fhir/r5/utils/DefinitionNavigator.java | 4 +- .../r5/utils/ElementDefinitionUtilities.java | 2 +- .../org/hl7/fhir/r5/utils/FHIRPathEngine.java | 8 +- .../fhir/r5/utils/GraphQLSchemaGenerator.java | 12 +-- .../hl7/fhir/r5/utils/NarrativeGenerator.java | 18 ++-- .../hl7/fhir/r5/utils/ProtoBufGenerator.java | 6 +- .../fhir/r5/utils/QuestionnaireBuilder.java | 89 ++++++++++--------- .../hl7/fhir/r5/utils/ResourceUtilities.java | 2 +- .../fhir/r5/utils/StructureMapUtilities.java | 8 +- .../hl7/fhir/r5/utils/ToolingExtensions.java | 16 +++- .../hl7/fhir/r5/utils/formats/CSVWriter.java | 2 +- .../hl7/fhir/r5/utils/formats/XLSXWriter.java | 2 +- .../fhir/r5/test/SnapShotGenerationTests.java | 6 ++ .../fhir/r5/validation/InstanceValidator.java | 28 +++--- .../fhir/r5/validation/ProfileValidator.java | 4 +- 24 files changed, 236 insertions(+), 166 deletions(-) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/SpecDifferenceEvaluator.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/SpecDifferenceEvaluator.java index 882c13f71..9ccb4959f 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/SpecDifferenceEvaluator.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/SpecDifferenceEvaluator.java @@ -847,7 +847,7 @@ public class SpecDifferenceEvaluator { removed.append(describeType(tr)); } for (TypeRefComponent tr : rev.getType()) { - if (!hasType(orig.getType(), tr) && !isAbstractType(tr.getCode())) + if (!hasType(orig.getType(), tr) && !isAbstractType(tr.getWorkingCode())) added.append(describeType(tr)); } for (TypeRefComponent tr : rev.getType()) { @@ -882,9 +882,9 @@ public class SpecDifferenceEvaluator { } if (!added.isEmpty()) - bp.append("Type " +tr.getCode()+": Added Target "+Utilities.pluralize("Type", added.size())+" "+csv(added)); + bp.append("Type " +tr.getWorkingCode()+": Added Target "+Utilities.pluralize("Type", added.size())+" "+csv(added)); if (!removed.isEmpty()) - bp.append("Type " +tr.getCode()+": Removed Target "+Utilities.pluralize("Type", removed.size())+" "+csv(removed)); + bp.append("Type " +tr.getWorkingCode()+": Removed Target "+Utilities.pluralize("Type", removed.size())+" "+csv(removed)); } private String trimNS(String v) { @@ -913,7 +913,7 @@ public class SpecDifferenceEvaluator { private boolean hasType(List types, TypeRefComponent tr) { for (TypeRefComponent t : types) { - if (t.getCode().equals(tr.getCode())) { + if (t.getWorkingCode().equals(tr.getWorkingCode())) { if (((!t.hasProfile() && !tr.hasProfile()) || (t.getProfile().equals(tr.getProfile())))) return true; } @@ -923,7 +923,7 @@ public class SpecDifferenceEvaluator { private TypeRefComponent getType(List types, TypeRefComponent tr) { for (TypeRefComponent t : types) { - if (t.getCode().equals(tr.getCode())) { + if (t.getWorkingCode().equals(tr.getWorkingCode())) { return t; } } @@ -932,9 +932,9 @@ public class SpecDifferenceEvaluator { private String describeType(TypeRefComponent tr) { if (!tr.hasProfile() && !tr.hasTargetProfile()) - return tr.getCode(); - else if (Utilities.existsInList(tr.getCode(), "Reference", "canonical")) { - StringBuilder b = new StringBuilder(tr.getCode()); + return tr.getWorkingCode(); + else if (Utilities.existsInList(tr.getWorkingCode(), "Reference", "canonical")) { + StringBuilder b = new StringBuilder(tr.getWorkingCode()); b.append("("); boolean first = true; for (UriType u : tr.getTargetProfile()) { @@ -950,7 +950,7 @@ public class SpecDifferenceEvaluator { b.append(")"); return b.toString(); } else { - StringBuilder b = new StringBuilder(tr.getCode()); + StringBuilder b = new StringBuilder(tr.getWorkingCode()); if (tr.getProfile().size() > 0) { b.append("("); boolean first = true; @@ -1255,7 +1255,7 @@ public class SpecDifferenceEvaluator { oa.add(new JsonPrimitive(describeType(tr))); } for (TypeRefComponent tr : rev.getType()) { - if (!hasType(orig.getType(), tr) && !isAbstractType(tr.getCode())) + if (!hasType(orig.getType(), tr) && !isAbstractType(tr.getWorkingCode())) ra.add(new JsonPrimitive(describeType(tr))); } for (TypeRefComponent tr : rev.getType()) { @@ -1289,9 +1289,9 @@ public class SpecDifferenceEvaluator { } if (added.size() > 0) - element.add(tr.getCode()+"-target-added", added); + element.add(tr.getWorkingCode()+"-target-added", added); if (removed.size() > 0) - element.add(tr.getCode()+"-target-removed", removed); + element.add(tr.getWorkingCode()+"-target-removed", removed); } private void analyseTypes(Document doc, Element element, ElementDefinition rev, ElementDefinition orig) { @@ -1312,7 +1312,7 @@ public class SpecDifferenceEvaluator { element.appendChild(makeElementWithAttribute(doc, "removed-type", "name", describeType(tr))); } for (TypeRefComponent tr : rev.getType()) { - if (!hasType(orig.getType(), tr) && !isAbstractType(tr.getCode())) + if (!hasType(orig.getType(), tr) && !isAbstractType(tr.getWorkingCode())) element.appendChild(makeElementWithAttribute(doc, "added-type", "name", describeType(tr))); } for (TypeRefComponent tr : rev.getType()) { @@ -1328,13 +1328,13 @@ public class SpecDifferenceEvaluator { for (CanonicalType p : tr.getTargetProfile()) { if (!hasParam(tm, p.asStringValue())) { - element.appendChild(makeElementWithAttribute(doc, tr.getCode()+"-target-added", "name", p.asStringValue())); + element.appendChild(makeElementWithAttribute(doc, tr.getWorkingCode()+"-target-added", "name", p.asStringValue())); } } for (CanonicalType p : tm.getTargetProfile()) { if (!hasParam(tr, p.asStringValue())) { - element.appendChild(makeElementWithAttribute(doc, tr.getCode()+"-target-removed", "name", p.asStringValue())); + element.appendChild(makeElementWithAttribute(doc, tr.getWorkingCode()+"-target-removed", "name", p.asStringValue())); } } } diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_40_50.java index 87da62414..b4e74fb1a 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertor_40_50.java @@ -20,7 +20,12 @@ package org.hl7.fhir.convertors; * #L% */ +/* + * public static final String EXT_JSON_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type"; + public static final String EXT_RDF_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type"; + public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; + */ import org.hl7.fhir.convertors.conv40_50.*; import org.hl7.fhir.exceptions.FHIRException; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileComparer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileComparer.java index 3fb5b9e43..1fec6b769 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileComparer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ProfileComparer.java @@ -891,7 +891,7 @@ public class ProfileComparer { if (nw.hasAggregation()) throw new DefinitionException("Aggregation not supported: "+path); for (TypeRefComponent ex : results) { - if (Utilities.equals(ex.getCode(), nw.getCode())) { + if (Utilities.equals(ex.getWorkingCode(), nw.getWorkingCode())) { if (!ex.hasProfile() && !nw.hasProfile()) pfound = true; else if (!ex.hasProfile()) { @@ -1070,7 +1070,7 @@ public class ProfileComparer { private String typeCode(DefinitionNavigator defn) { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); for (TypeRefComponent t : defn.current().getType()) - b.append(t.getCode()+(t.hasProfile() ? "("+t.getProfile()+")" : "")+(t.hasTargetProfile() ? "("+t.getTargetProfile()+")" : "")); // todo: other properties + b.append(t.getWorkingCode()+(t.hasProfile() ? "("+t.getProfile()+")" : "")+(t.hasTargetProfile() ? "("+t.getTargetProfile()+")" : "")); // todo: other properties return b.toString(); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java index 094516cf4..c1775c5cd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java @@ -34,6 +34,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.model.Constants; import org.hl7.fhir.r5.model.DomainResource; import org.hl7.fhir.r5.model.ElementDefinition; import org.hl7.fhir.r5.model.Enumerations; @@ -568,7 +569,7 @@ public class ShExGenerator { private String genTypeRef(StructureDefinition sd, ElementDefinition ed, String id, ElementDefinition.TypeRefComponent typ) { if(typ.hasProfile()) { - if(typ.getCode().equals("Reference")) + if(typ.getWorkingCode().equals("Reference")) return genReference("", typ); else if(ProfileUtilities.getChildList(sd, ed).size() > 0) { // inline anonymous type - give it a name and factor it out @@ -581,13 +582,8 @@ public class ShExGenerator { return simpleElement(sd, ed, ref); } - } else if (typ.getCodeElement().getExtensionsByUrl(ToolingExtensions.EXT_RDF_TYPE).size() > 0) { - String xt = null; - try { - xt = typ.getCodeElement().getExtensionString(ToolingExtensions.EXT_RDF_TYPE); - } catch (FHIRException e) { - e.printStackTrace(); - } + } else if (typ.getWorkingCode().startsWith(Constants.NS_SYSTEM_TYPE)) { + String xt = typ.getWorkingCode(); // TODO: Remove the next line when the type of token gets switched to string // TODO: Add a rdf-type entry for valueInteger to xsd:integer (instead of int) ST td_entry = tmplt(PRIMITIVE_ELEMENT_DEFN_TEMPLATE).add("typ", @@ -612,16 +608,16 @@ public class ShExGenerator { td_entry.add("facets", facets.toString()); return td_entry.render(); - } else if (typ.getCode() == null) { + } else if (typ.getWorkingCode() == null) { ST primitive_entry = tmplt(PRIMITIVE_ELEMENT_DEFN_TEMPLATE); primitive_entry.add("typ", "xsd:string"); return primitive_entry.render(); - } else if(typ.getCode().equals("xhtml")) { + } else if(typ.getWorkingCode().equals("xhtml")) { return tmplt(XHTML_TYPE_TEMPLATE).render(); } else { - datatypes.add(typ.getCode()); - return simpleElement(sd, ed, typ.getCode()); + datatypes.add(typ.getWorkingCode()); + return simpleElement(sd, ed, typ.getWorkingCode()); } } @@ -653,8 +649,8 @@ public class ShExGenerator { * @return ShEx equivalent */ private String genAltEntry(String id, ElementDefinition.TypeRefComponent typ) { - if(!typ.getCode().equals("Reference")) - throw new AssertionError("We do not handle " + typ.getCode() + " alternatives"); + if(!typ.getWorkingCode().equals("Reference")) + throw new AssertionError("We do not handle " + typ.getWorkingCode() + " alternatives"); return genReference(id, typ); } @@ -685,7 +681,7 @@ public class ShExGenerator { private String genChoiceEntry(StructureDefinition sd, ElementDefinition ed, String id, String base, ElementDefinition.TypeRefComponent typ) { ST shex_choice_entry = tmplt(ELEMENT_TEMPLATE); - String ext = typ.getCode(); + String ext = typ.getWorkingCode(); shex_choice_entry.add("id", "fhir:" + base+Character.toUpperCase(ext.charAt(0)) + ext.substring(1) + " "); shex_choice_entry.add("card", ""); shex_choice_entry.add("defn", genTypeRef(sd, ed, id, typ)); @@ -745,7 +741,7 @@ public class ShExGenerator { String[] els = typ.getProfile().get(0).getValue().split("/"); return els[els.length - 1]; } else { - return typ.getCode(); + return typ.getWorkingCode(); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/XmlSchemaGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/XmlSchemaGenerator.java index b4b9741ea..6fa652aa8 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/XmlSchemaGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/XmlSchemaGenerator.java @@ -355,7 +355,7 @@ public class XmlSchemaGenerator { throw new Error("Common ancester not found at "+edc.getPath()); CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); for (TypeRefComponent t : edc.getType()) { - b.append(getQN(sd, edc, t.getCode(), true).toString()); + b.append(getQN(sd, edc, t.getWorkingCode(), true).toString()); } String name = tailDot(edc.getPath()); @@ -376,8 +376,8 @@ public class XmlSchemaGenerator { } else for (TypeRefComponent t : edc.getType()) { String name = tailDot(edc.getPath()); if (edc.getType().size() > 1) - name = name + Utilities.capitalize(t.getCode()); - QName qn = getQN(sd, edc, t.getCode(), true); + name = name + Utilities.capitalize(t.getWorkingCode()); + QName qn = getQN(sd, edc, t.getWorkingCode(), true); String min = String.valueOf(edc.getMin()); String max = edc.getMax(); if ("*".equals(max)) @@ -436,13 +436,13 @@ public class XmlSchemaGenerator { } private StructureDefinition getCommonAncestor(List type) throws FHIRException { - StructureDefinition sd = library.get(type.get(0).getCode()); + StructureDefinition sd = library.get(type.get(0).getWorkingCode()); if (sd == null) - throw new FHIRException("Unable to find definition for "+type.get(0).getCode()); + throw new FHIRException("Unable to find definition for "+type.get(0).getWorkingCode()); for (int i = 1; i < type.size(); i++) { - StructureDefinition t = library.get(type.get(i).getCode()); + StructureDefinition t = library.get(type.get(i).getWorkingCode()); if (t == null) - throw new FHIRException("Unable to find definition for "+type.get(i).getCode()); + throw new FHIRException("Unable to find definition for "+type.get(i).getWorkingCode()); sd = getCommonAncestor(sd, t); } return sd; @@ -520,10 +520,11 @@ public class XmlSchemaGenerator { // if (!max.equals("1")) // throw new FHIRException("Illegal cardinality \""+max+"\" for attribute "+edc.getPath()); - if (Utilities.isAbsoluteUrl(t.getCode())) - throw new FHIRException("Only FHIR primitive types are supported for attributes ("+t.getCode()+")"); + String tc = t.getWorkingCode(); + if (Utilities.isAbsoluteUrl(tc)) + throw new FHIRException("Only FHIR primitive types are supported for attributes ("+tc+")"); String typeNs = namespaces.get("http://hl7.org/fhir"); - String type = t.getCode(); + String type = tc; w(" processed, Property property) { + if (property.isChoice()) { + for (TypeRefComponent type : property.getDefinition().getType()) { + String eName = property.getName().substring(0, property.getName().length()-3) + Utilities.capitalize(type.getWorkingCode()); + if (!isPrimitive(type.getWorkingCode()) && object.has(eName)) { + parseChildComplex(path, object, context, processed, property, eName); + break; + } else if (isPrimitive(type.getWorkingCode()) && (object.has(eName) || object.has("_"+eName))) { + parseChildPrimitive(object, context, processed, property, path, eName); + break; + } + } + } else if (property.isPrimitive(property.getType(null))) { + parseChildPrimitive(object, context, processed, property, path, property.getName()); + } else if (object.has(property.getName())) { + parseChildComplex(path, object, context, processed, property, property.getName()); + } + } + private void parseChildComplex(String path, JsonObject object, Element context, Set processed, Property property, String name) throws FHIRException { processed.add(name); String npath = path+"/"+property.getName(); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java index 6786400cb..1e6c051a7 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java @@ -64,14 +64,14 @@ public class Property { if (definition.getType().size() == 0) return null; else if (definition.getType().size() > 1) { - String tn = definition.getType().get(0).getCode(); + String tn = definition.getType().get(0).getWorkingCode(); for (int i = 1; i < definition.getType().size(); i++) { - if (!tn.equals(definition.getType().get(i).getCode())) + if (!tn.equals(definition.getType().get(i).getWorkingCode())) throw new Error("logic error, gettype when types > 1"); } return tn; } else - return definition.getType().get(0).getCode(); + return definition.getType().get(0).getWorkingCode(); } public String getType(String elementName) { @@ -114,7 +114,7 @@ public class Property { else return structure.getId(); } else - return ed.getType().get(0).getCode(); + return ed.getType().get(0).getWorkingCode(); } public boolean hasType(String elementName) { @@ -251,14 +251,14 @@ public class Property { // ok, find the right definitions String t = null; if (ed.getType().size() == 1) - t = ed.getType().get(0).getCode(); + t = ed.getType().get(0).getWorkingCode(); else if (ed.getType().size() == 0) throw new Error("types == 0, and no children found on "+getDefinition().getPath()); else { - t = ed.getType().get(0).getCode(); + t = ed.getType().get(0).getWorkingCode(); boolean all = true; for (TypeRefComponent tr : ed.getType()) { - if (!tr.getCode().equals(t)) { + if (!tr.getWorkingCode().equals(t)) { all = false; break; } @@ -271,12 +271,12 @@ public class Property { t = ToolingExtensions.readStringExtension(ed, "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaulttype"); boolean ok = false; for (TypeRefComponent tr : ed.getType()) { - if (tr.getCode().equals(t)) + if (tr.getWorkingCode().equals(t)) ok = true; - if (Utilities.isAbsoluteUrl(tr.getCode())) { - StructureDefinition sdt = context.fetchResource(StructureDefinition.class, tr.getCode()); + if (Utilities.isAbsoluteUrl(tr.getWorkingCode())) { + StructureDefinition sdt = context.fetchResource(StructureDefinition.class, tr.getWorkingCode()); if (sdt != null && sdt.getType().equals(t)) { - url = tr.getCode(); + url = tr.getWorkingCode(); ok = true; } } @@ -295,7 +295,7 @@ public class Property { } if (!"xhtml".equals(t)) { for (TypeRefComponent aType: ed.getType()) { - if (aType.getCode().equals(t)) { + if (aType.getWorkingCode().equals(t)) { if (aType.hasProfile()) { assert aType.getProfile().size() == 1; url = aType.getProfile().get(0).getValue(); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java index 1c4185fd3..9528b625f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java @@ -60,4 +60,6 @@ public class Constants { public final static String DATE = "Thu Dec 13 14:07:26 AEDT 2018"; public final static String URI_REGEX = "((http|https)://([A-Za-z0-9\\\\\\.\\:\\%\\$]*\\/)*)?(Account|ActivityDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|CatalogEntry|ChargeItem|ChargeItemDefinition|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceDefinition|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EffectEvidenceSynthesis|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|InsurancePlan|Invoice|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProduct|MedicinalProductAuthorization|MedicinalProductContraindication|MedicinalProductIndication|MedicinalProductIngredient|MedicinalProductInteraction|MedicinalProductManufactured|MedicinalProductPackaged|MedicinalProductPharmaceutical|MedicinalProductUndesirableEffect|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionOrder|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RelatedPerson|RequestGroup|ResearchDefinition|ResearchElementDefinition|ResearchStudy|ResearchSubject|RiskAssessment|RiskEvidenceSynthesis|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|Substance|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SubstanceSpecification|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestReport|TestScript|ValueSet|VerificationResult|VisionPrescription)\\/[A-Za-z0-9\\-\\.]{1,64}(\\/_history\\/[A-Za-z0-9\\-\\.]{1,64})?"; public final static String LOCAL_REF_REGEX = "(Account|ActivityDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|CatalogEntry|ChargeItem|ChargeItemDefinition|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceDefinition|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EffectEvidenceSynthesis|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|InsurancePlan|Invoice|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProduct|MedicinalProductAuthorization|MedicinalProductContraindication|MedicinalProductIndication|MedicinalProductIngredient|MedicinalProductInteraction|MedicinalProductManufactured|MedicinalProductPackaged|MedicinalProductPharmaceutical|MedicinalProductUndesirableEffect|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionOrder|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RelatedPerson|RequestGroup|ResearchDefinition|ResearchElementDefinition|ResearchStudy|ResearchSubject|RiskAssessment|RiskEvidenceSynthesis|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|Substance|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SubstanceSpecification|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestReport|TestScript|ValueSet|VerificationResult|VisionPrescription)\\/[A-Za-z0-9\\-\\.]{1,64}"; + public final static String NS_SYSTEM_TYPE = "http://hl7.org/fhirpath/System."; + } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java index 90932d1b3..138ccf3ae 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java @@ -58,6 +58,7 @@ import org.hl7.fhir.instance.model.api.IBaseDatatypeElement; import org.hl7.fhir.instance.model.api.ICompositeType; import org.hl7.fhir.r5.model.Enumerations.BindingStrength; import org.hl7.fhir.r5.model.Enumerations.BindingStrengthEnumFactory; +import org.hl7.fhir.r5.utils.ToolingExtensions; // added from java-adornments.txt: import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.Utilities; @@ -2256,6 +2257,50 @@ public class ElementDefinition extends BackboneType implements ICompositeType { return Utilities.existsInList(getCode(), "Reference", "canonical"); } + /** + * This code checks for the system prefix and returns the FHIR type + * + * @return + */ + public String getWorkingCode() { + if (hasExtension(ToolingExtensions.EXT_FHIR_TYPE)) + return getExtensionString(ToolingExtensions.EXT_FHIR_TYPE); + if (!hasCodeElement()) + return null; + if (getCodeElement().hasExtension(ToolingExtensions.EXT_XML_TYPE)) { + String s = getCodeElement().getExtensionString(ToolingExtensions.EXT_XML_TYPE); + if ("xsd:gYear OR xsd:gYearMonth OR xsd:date OR xsd:dateTime".equals(s)) + return "dateTime"; + if ("xsd:gYear OR xsd:gYearMonth OR xsd:date".equals(s)) + return "date"; + if ("xsd:dateTime".equals(s)) + return "instant"; + if ("xsd:token".equals(s)) + return "code"; + if ("xsd:boolean".equals(s)) + return "boolean"; + if ("xsd:string".equals(s)) + return "string"; + if ("xsd:time".equals(s)) + return "time"; + if ("xsd:int".equals(s)) + return "integer"; + if ("xsd:decimal OR xsd:double".equals(s)) + return "decimal"; + if ("xsd:base64Binary".equals(s)) + return "base64Binary"; + if ("xsd:positiveInteger".equals(s)) + return "positiveInt"; + if ("xsd:nonNegativeInteger".equals(s)) + return "unsignedInt"; + if ("xsd:anyURI".equals(s)) + return "uri"; + + throw new Error("Unknown xml type '"+s+"'"); + } + return getCode(); + } + // end addition } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/DefinitionNavigator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/DefinitionNavigator.java index 6cc23282e..ad9c1a6ed 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/DefinitionNavigator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/DefinitionNavigator.java @@ -166,12 +166,12 @@ public class DefinitionNavigator { private void loadTypedChildren(TypeRefComponent type) throws DefinitionException { typeOfChildren = null; - StructureDefinition sd = context.fetchResource(StructureDefinition.class, /* GF#13465 : this somehow needs to be revisited type.hasProfile() ? type.getProfile() : */ type.getCode()); + StructureDefinition sd = context.fetchResource(StructureDefinition.class, /* GF#13465 : this somehow needs to be revisited type.hasProfile() ? type.getProfile() : */ type.getWorkingCode()); if (sd != null) { DefinitionNavigator dn = new DefinitionNavigator(context, sd, 0, path, names, sd.getType()); typeChildren = dn.children(); } else - throw new DefinitionException("Unable to find definition for "+type.getCode()+(type.hasProfile() ? "("+type.getProfile()+")" : "")); + throw new DefinitionException("Unable to find definition for "+type.getWorkingCode()+(type.hasProfile() ? "("+type.getProfile()+")" : "")); typeOfChildren = type; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ElementDefinitionUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ElementDefinitionUtilities.java index 9128ef1d7..27d1f4088 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ElementDefinitionUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ElementDefinitionUtilities.java @@ -31,7 +31,7 @@ public class ElementDefinitionUtilities { return false; for (TypeRefComponent tr : ed.getType()) { - if (name.equals(tr.getCode())) + if (name.equals(tr.getWorkingCode())) return true; } return false; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java index bea62f7db..9b2be7cc0 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java @@ -3518,8 +3518,10 @@ public class FHIRPathEngine { String st = convertToString(focus.get(0)); if (Utilities.noString(st)) result.add(new BooleanType(false).noExtensions()); - else - result.add(new BooleanType(st.matches(sw)).noExtensions()); + else { + boolean ok = st.matches(sw); + result.add(new BooleanType(ok).noExtensions()); + } } else result.add(new BooleanType(false).noExtensions()); return result; @@ -3913,7 +3915,7 @@ public class FHIRPathEngine { throw new PathEngineException("No type provided in BuildToolPathEvaluator.getChildTypesByName"); if (type.equals("http://hl7.org/fhir/StructureDefinition/xhtml")) return; - if (type.startsWith("http://hl7.org/fhir/StructureDefinition/System.")) + if (type.startsWith(Constants.NS_SYSTEM_TYPE)) return; if (type.equals(TypeDetails.FP_SimpleTypeInfo)) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/GraphQLSchemaGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/GraphQLSchemaGenerator.java index e89eaa8b3..e1e80c49e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/GraphQLSchemaGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/GraphQLSchemaGenerator.java @@ -297,18 +297,18 @@ public class GraphQLSchemaGenerator { private void generateProperty(List list, StringBuilder b, String typeName, StructureDefinition sd, ElementDefinition child, TypeRefComponent typeDetails, boolean suffix, ElementDefinition cr, String mode, String suffixS) throws IOException { if (isPrimitive(typeDetails)) { - String n = getGqlname(typeDetails.getCode()); + String n = getGqlname(typeDetails.getWorkingCode()); b.append(" "); b.append(tail(child.getPath(), suffix)); if (suffix) - b.append(Utilities.capitalize(typeDetails.getCode())); + b.append(Utilities.capitalize(typeDetails.getWorkingCode())); b.append(": "); b.append(n); if (!child.getPath().endsWith(".id")) { b.append(" _"); b.append(tail(child.getPath(), suffix)); if (suffix) - b.append(Utilities.capitalize(typeDetails.getCode())); + b.append(Utilities.capitalize(typeDetails.getWorkingCode())); if (!child.getMax().equals("1")) b.append(": [ElementBase]\r\n"); else @@ -319,11 +319,11 @@ public class GraphQLSchemaGenerator { b.append(" "); b.append(tail(child.getPath(), suffix)); if (suffix) - b.append(Utilities.capitalize(typeDetails.getCode())); + b.append(Utilities.capitalize(typeDetails.getWorkingCode())); b.append(": "); if (!child.getMax().equals("1")) b.append("["); - String type = typeDetails.getCode(); + String type = typeDetails.getWorkingCode(); if (cr != null) b.append(generateInnerType(list, sd, typeName, cr, mode, suffixS)); else if (Utilities.existsInList(type, "Element", "BackboneElement")) @@ -366,7 +366,7 @@ public class GraphQLSchemaGenerator { } private boolean isPrimitive(TypeRefComponent type) { - String typeName = type.getCode(); + String typeName = type.getWorkingCode(); StructureDefinition sd = context.fetchTypeDefinition(typeName); if (sd == null) return false; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java index 5260efc50..b3ef17728 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java @@ -500,9 +500,9 @@ public class NarrativeGenerator implements INarrativeGenerator { if (definition.getType().isEmpty()) return null; if (definition.getType().size() == 1) { - if (definition.getType().get(0).getCode().equals("Element") || definition.getType().get(0).getCode().equals("BackboneElement")) + if (definition.getType().get(0).getWorkingCode().equals("Element") || definition.getType().get(0).getWorkingCode().equals("BackboneElement")) return null; - return definition.getType().get(0).getCode(); + return definition.getType().get(0).getWorkingCode(); } String t = e.getNodeName().substring(tail(definition.getPath()).length()-3); @@ -521,7 +521,7 @@ public class NarrativeGenerator implements INarrativeGenerator { public String getTypeCode() { if (definition == null || definition.getType().size() != 1) throw new Error("not handled"); - return definition.getType().get(0).getCode(); + return definition.getType().get(0).getWorkingCode(); } @Override @@ -1303,7 +1303,7 @@ public class NarrativeGenerator implements INarrativeGenerator { private boolean renderAsList(ElementDefinition child) { if (child.getType().size() == 1) { - String t = child.getType().get(0).getCode(); + String t = child.getType().get(0).getWorkingCode(); if (t.equals("Address") || t.equals("Reference")) return true; } @@ -1358,7 +1358,7 @@ public class NarrativeGenerator implements INarrativeGenerator { //we can tell if e is a primitive because it has types if (e.getType().isEmpty()) return false; - if (e.getType().size() == 1 && isBase(e.getType().get(0).getCode())) + if (e.getType().size() == 1 && isBase(e.getType().get(0).getWorkingCode())) return false; return true; // return !e.getType().isEmpty() @@ -1683,7 +1683,7 @@ public class NarrativeGenerator implements INarrativeGenerator { if (child.getMustSupport()) return true; if (child.getType().size() == 1) { - String t = child.getType().get(0).getCode(); + String t = child.getType().get(0).getWorkingCode(); if (t.equals("Address") || t.equals("Contact") || t.equals("Reference") || t.equals("Uri") || t.equals("Url") || t.equals("Canonical")) return false; } @@ -3043,7 +3043,7 @@ public class NarrativeGenerator implements INarrativeGenerator { if (ToolingExtensions.EXT_TRANSLATION.equals(ext.getUrl())) { String l = ToolingExtensions.readStringExtension(ext, "lang"); if (lang.equals(l)) - d = ToolingExtensions.readStringExtension(ext, "content");; + d = ToolingExtensions.readStringExtension(ext, "content"); } } tr.td().addText(d == null ? "" : d); @@ -3127,9 +3127,7 @@ public class NarrativeGenerator implements INarrativeGenerator { private boolean checkDoSystem(ValueSet vs, ValueSet src) { if (src != null) vs = src; - if (vs.hasCompose()) - return true; - return false; + return vs.hasCompose(); } private boolean IsNotFixedExpansion(ValueSet vs) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ProtoBufGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ProtoBufGenerator.java index 1ba73e9fe..759ba1fde 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ProtoBufGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ProtoBufGenerator.java @@ -114,18 +114,18 @@ public class ProtoBufGenerator { if (ed.getType().size() != 1) fld.type = "Unknown"; else { - StructureDefinition td = context.fetchTypeDefinition(ed.getTypeFirstRep().getCode()); + StructureDefinition td = context.fetchTypeDefinition(ed.getTypeFirstRep().getWorkingCode()); if (td == null) fld.type = "Unresolved"; else if (td.getKind() == StructureDefinitionKind.PRIMITIVETYPE) { - fld.type = protoTypeForFhirType(ed.getTypeFirstRep().getCode()); + fld.type = protoTypeForFhirType(ed.getTypeFirstRep().getWorkingCode()); fld = new Field(); fld.name = tail(ed.getPath())+"Extra"; fld.repeating = (!ed.getMax().equals("1")); fld.type = "Primitive"; message.fields.add(fld); } else - fld.type = ed.getTypeFirstRep().getCode(); + fld.type = ed.getTypeFirstRep().getWorkingCode(); } } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java index 58aa9ba2e..86d575a10 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java @@ -316,11 +316,11 @@ public class QuestionnaireBuilder { } private boolean isAbstractType(List type) { - return type.size() == 1 && (type.get(0).getCode().equals("Element") || type.get(0).getCode().equals("BackboneElement")); + return type.size() == 1 && (type.get(0).getWorkingCode().equals("Element") || type.get(0).getWorkingCode().equals("BackboneElement")); } private boolean isInlineDataType(List type) { - return type.size() == 1 && !Utilities.existsInList(type.get(0).getCode(), "code", "string", "id", "oid", "markdown", "uri", "boolean", "decimal", "dateTime", "date", "instant", "time", "CodeableConcept", "Period", "Ratio", + return type.size() == 1 && !Utilities.existsInList(type.get(0).getWorkingCode(), "code", "string", "id", "oid", "markdown", "uri", "boolean", "decimal", "dateTime", "date", "instant", "time", "CodeableConcept", "Period", "Ratio", "HumanName", "Address", "ContactPoint", "Identifier", "integer", "positiveInt", "unsignedInt", "Coding", "Quantity", "Count", "Age", "Duration", "Distance", "Money", "Money", "Reference", "Duration", "base64Binary", "Attachment", "Age", "Range", "Timing", "Annotation", "SampledData", "Extension", "SampledData", "Narrative", "Resource", "Meta", "url", "canonical"); @@ -330,7 +330,7 @@ public class QuestionnaireBuilder { String n = tail(child.getPath()); String t = ""; if (!element.getType().isEmpty()) - t = element.getType().get(0).getCode(); + t = element.getType().get(0).getWorkingCode(); // we don't generate questions for the base stuff in every element if (t.equals("Resource") && (n.equals("text") || n.equals("language") || n.equals("contained"))) @@ -385,7 +385,7 @@ public class QuestionnaireBuilder { else ToolingExtensions.addFlyOver(group, element.getDefinition()); - if (element.getType().size() > 1 || element.getType().get(0).getCode().equals("*")) { + if (element.getType().size() > 1 || element.getType().get(0).getWorkingCode().equals("*")) { List types = expandTypeList(element.getType()); Questionnaire.QuestionnaireItemComponent q = addQuestion(group, QuestionnaireItemType.CHOICE, element.getPath(), "_type", "type", null, makeTypeList(profile, types, element.getPath())); for (TypeRefComponent t : types) { @@ -410,7 +410,7 @@ public class QuestionnaireBuilder { for (TypeRefComponent t : types) { if (t.hasProfile()) result.add(t); - else if (t.getCode().equals("*")) { + else if (t.getWorkingCode().equals("*")) { result.add(new TypeRefComponent().setCode("integer")); result.add(new TypeRefComponent().setCode("decimal")); result.add(new TypeRefComponent().setCode("dateTime")); @@ -459,8 +459,8 @@ public class QuestionnaireBuilder { } } else if (!t.hasProfile()) { ValueSetExpansionContainsComponent cc = vs.getExpansion().addContains(); - cc.setCode(t.getCode()); - cc.setDisplay(t.getCode()); + cc.setCode(t.getWorkingCode()); + cc.setDisplay(t.getWorkingCode()); cc.setSystem("http://hl7.org/fhir/data-types"); } else for (UriType u : t.getProfile()) { ProfileUtilities pu = new ProfileUtilities(context, null, null); @@ -514,7 +514,7 @@ public class QuestionnaireBuilder { cc.setCode(t.getProfile().get(0).getValue()); cc.setSystem("http://hl7.org/fhir/resource-types"); } else { - cc.setCode(t.getCode()); + cc.setCode(t.getWorkingCode()); cc.setSystem("http://hl7.org/fhir/data-types"); } } @@ -529,7 +529,7 @@ public class QuestionnaireBuilder { } private boolean instanceOf(TypeRefComponent t, Element obj) { - if (t.getCode().equals("Reference")) { + if (t.getWorkingCode().equals("Reference")) { if (!(obj instanceof Reference)) { return false; } else { @@ -542,7 +542,7 @@ public class QuestionnaireBuilder { else return true; } - } else if (t.getCode().equals("Quantity")) { + } else if (t.getWorkingCode().equals("Quantity")) { return obj instanceof Quantity; } else throw new NotImplementedException("Not Done Yet"); @@ -703,77 +703,78 @@ public class QuestionnaireBuilder { } private boolean isPrimitive(TypeRefComponent t) { - String code = t.getCode(); + String code = t.getWorkingCode(); StructureDefinition sd = context.fetchTypeDefinition(code); return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE; } private void processDataType(StructureDefinition profile, QuestionnaireItemComponent group, ElementDefinition element, String path, TypeRefComponent t, List answerGroups, List parents) throws FHIRException { - if (t.getCode().equals("code")) + String tc = t.getWorkingCode(); + if (tc.equals("code")) addCodeQuestions(group, element, path, answerGroups); - else if (Utilities.existsInList(t.getCode(), "string", "id", "oid", "uuid", "markdown")) + else if (Utilities.existsInList(tc, "string", "id", "oid", "uuid", "markdown")) addStringQuestions(group, element, path, answerGroups); - else if (Utilities.existsInList(t.getCode(), "uri", "url", "canonical")) + else if (Utilities.existsInList(tc, "uri", "url", "canonical")) addUriQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("boolean")) + else if (tc.equals("boolean")) addBooleanQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("decimal")) + else if (tc.equals("decimal")) addDecimalQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("dateTime") || t.getCode().equals("date")) + else if (tc.equals("dateTime") || tc.equals("date")) addDateTimeQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("instant")) + else if (tc.equals("instant")) addInstantQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("time")) + else if (tc.equals("time")) addTimeQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("CodeableConcept")) + else if (tc.equals("CodeableConcept")) addCodeableConceptQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Period")) + else if (tc.equals("Period")) addPeriodQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Ratio")) + else if (tc.equals("Ratio")) addRatioQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("HumanName")) + else if (tc.equals("HumanName")) addHumanNameQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Address")) + else if (tc.equals("Address")) addAddressQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("ContactPoint")) + else if (tc.equals("ContactPoint")) addContactPointQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Identifier")) + else if (tc.equals("Identifier")) addIdentifierQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("integer") || t.getCode().equals("positiveInt") || t.getCode().equals("unsignedInt") ) + else if (tc.equals("integer") || tc.equals("positiveInt") || tc.equals("unsignedInt") ) addIntegerQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Coding")) + else if (tc.equals("Coding")) addCodingQuestions(group, element, path, answerGroups); - else if (Utilities.existsInList(t.getCode(), "Quantity", "Count", "Age", "Duration", "Distance", "Money")) + else if (Utilities.existsInList(tc, "Quantity", "Count", "Age", "Duration", "Distance", "Money")) addQuantityQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Money")) + else if (tc.equals("Money")) addMoneyQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Reference")) + else if (tc.equals("Reference")) addReferenceQuestions(group, element, path, t.getTargetProfile(), answerGroups); - else if (t.getCode().equals("Duration")) + else if (tc.equals("Duration")) addDurationQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("base64Binary")) + else if (tc.equals("base64Binary")) addBinaryQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Attachment")) + else if (tc.equals("Attachment")) addAttachmentQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Age")) + else if (tc.equals("Age")) addAgeQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Range")) + else if (tc.equals("Range")) addRangeQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Timing")) + else if (tc.equals("Timing")) addTimingQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Annotation")) + else if (tc.equals("Annotation")) addAnnotationQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("SampledData")) + else if (tc.equals("SampledData")) addSampledDataQuestions(group, element, path, answerGroups); - else if (t.getCode().equals("Extension")) { + else if (tc.equals("Extension")) { if (t.hasProfile()) addExtensionQuestions(profile, group, element, path, t.getProfile().get(0).getValue(), answerGroups, parents); - } else if (t.getCode().equals("SampledData")) + } else if (tc.equals("SampledData")) addSampledDataQuestions(group, element, path, answerGroups); - else if (!t.getCode().equals("Narrative") && !t.getCode().equals("Resource") && !t.getCode().equals("Meta") && !t.getCode().equals("Signature")) { - StructureDefinition sd = context.fetchTypeDefinition(t.getCode()); + else if (!tc.equals("Narrative") && !tc.equals("Resource") && !tc.equals("Meta") && !tc.equals("Signature")) { + StructureDefinition sd = context.fetchTypeDefinition(tc); if (sd == null) - throw new NotImplementedException("Unhandled Data Type: "+t.getCode()+" on element "+element.getPath()); + throw new NotImplementedException("Unhandled Data Type: "+tc+" on element "+element.getPath()); buildGroup(group, sd, sd.getSnapshot().getElementFirstRep(), parents, answerGroups); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceUtilities.java index faa9fce07..4e19f4752 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ResourceUtilities.java @@ -363,7 +363,7 @@ public class ResourceUtilities { private static String renderType(TypeRefComponent type) { if (type == null || type.isEmpty()) return ""; - return type.getCode(); + return type.getWorkingCode(); } public static void renderContactPoint(StringBuilder b, ContactPoint cp) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/StructureMapUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/StructureMapUtilities.java index 99339284f..1d596785e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/StructureMapUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/StructureMapUtilities.java @@ -2452,7 +2452,7 @@ public class StructureMapUtilities { for (TypeRefComponent tr : element.getDefinition().getType()) { if (!tr.hasCode()) throw new Error("Rule \""+ruleId+"\": Element has no type"); - ProfiledType pt = new ProfiledType(tr.getCode()); + ProfiledType pt = new ProfiledType(tr.getWorkingCode()); if (tr.hasProfile()) pt.addProfiles(tr.getProfile()); if (element.getDefinition().hasBinding()) @@ -2710,11 +2710,11 @@ public class StructureMapUtilities { private String checkType(String t, Property pvb, List profiles) throws FHIRException { - if (pvb.getDefinition().getType().size() == 1 && isCompatibleType(t, pvb.getDefinition().getType().get(0).getCode()) && profilesMatch(profiles, pvb.getDefinition().getType().get(0).getProfile())) + if (pvb.getDefinition().getType().size() == 1 && isCompatibleType(t, pvb.getDefinition().getType().get(0).getWorkingCode()) && profilesMatch(profiles, pvb.getDefinition().getType().get(0).getProfile())) return null; for (TypeRefComponent tr : pvb.getDefinition().getType()) { - if (isCompatibleType(t, tr.getCode())) - return tr.getCode(); // note what is returned - the base type, not the inferred mapping type + if (isCompatibleType(t, tr.getWorkingCode())) + return tr.getWorkingCode(); // note what is returned - the base type, not the inferred mapping type } throw new FHIRException("The type "+t+" is not compatible with the allowed types for "+pvb.getDefinition().getPath()); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java index 075e111fa..fd90bc4af 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java @@ -105,9 +105,6 @@ public class ToolingExtensions { public static final String EXT_ISSUE_COL = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col"; public static final String EXT_DISPLAY_HINT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-display-hint"; public static final String EXT_REPLACED_BY = "http://hl7.org/fhir/StructureDefinition/valueset-replacedby"; - public static final String EXT_JSON_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type"; - public static final String EXT_RDF_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type"; - public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; public static final String EXT_REGEX = "http://hl7.org/fhir/StructureDefinition/regex"; public static final String EXT_CONTROL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl"; public static final String EXT_MINOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-minOccurs"; @@ -163,6 +160,8 @@ public class ToolingExtensions { public static final String EXT_MAPPING_TGTCARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-cardinality"; public static final String EXT_PRIVATE_BASE = "http://hl7.org/fhir/tools/"; public static final String EXT_ALLOWED_TYPE = "http://hl7.org/fhir/StructureDefinition/operationdefinition-allowed-type"; + public static final String EXT_FHIR_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type"; + public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; // specific extension helpers @@ -214,6 +213,16 @@ public class ToolingExtensions { } } + public static void addCodeExtension(Element e, String url, String content) { + if (!StringUtils.isBlank(content)) { + Extension ex = getExtension(e, url); + if (ex != null) + ex.setValue(new CodeType(content)); + else + e.getExtension().add(Factory.newExtension(url, new CodeType(content), true)); + } + } + public static void addStringExtension(DomainResource e, String url, String content) { if (!StringUtils.isBlank(content)) { Extension ex = getExtension(e, url); @@ -224,6 +233,7 @@ public class ToolingExtensions { } } + public static void addBooleanExtension(Element e, String url, boolean content) { Extension ex = getExtension(e, url); if (ex != null) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java index cb96b1cb4..fcd7db7aa 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/CSVWriter.java @@ -230,7 +230,7 @@ public class CSVWriter extends TextStreamWriter { val = o.toString(); } else if (o instanceof TypeRefComponent) { TypeRefComponent t = (TypeRefComponent)o; - val = t.getCode() + (t.getProfile() == null ? "" : " {" + t.getProfile() + "}") +(t.getTargetProfile() == null ? "" : " {" + t.getTargetProfile() + "}") + (t.getAggregation() == null || t.getAggregation().isEmpty() ? "" : " (" + itemList(t.getAggregation()) + ")"); + val = t.getWorkingCode() + (t.getProfile() == null ? "" : " {" + t.getProfile() + "}") +(t.getTargetProfile() == null ? "" : " {" + t.getTargetProfile() + "}") + (t.getAggregation() == null || t.getAggregation().isEmpty() ? "" : " (" + itemList(t.getAggregation()) + ")"); } else if (o instanceof Coding) { Coding t = (Coding)o; val = (t.getSystem()==null ? "" : t.getSystem()) + (t.getCode()==null ? "" : "#" + t.getCode()) + (t.getDisplay()==null ? "" : " (" + t.getDisplay() + ")"); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/XLSXWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/XLSXWriter.java index e95417b34..1716ce466 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/XLSXWriter.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/formats/XLSXWriter.java @@ -267,7 +267,7 @@ public class XLSXWriter extends TextStreamWriter { val = o.toString(); } else if (o instanceof TypeRefComponent) { TypeRefComponent t = (TypeRefComponent)o; - val = t.getCode(); + val = t.getWorkingCode(); if (val == null) val = ""; if (val.startsWith("http://hl7.org/fhir/StructureDefinition/")) diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java index bb9ed6e46..eebd92695 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java @@ -231,6 +231,12 @@ public class SnapShotGenerationTests { return false; } + @Override + public String getLinkForUrl(String corePath, String s) { + // TODO Auto-generated method stub + return null; + } + } private static class SnapShotGenerationTestsContext implements IEvaluationContext { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java index bd730f50c..30e41b786 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java @@ -1348,7 +1348,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat Set res = new HashSet(); if (vd != null && !"0".equals(vd.getMax())) { for (TypeRefComponent tr : vd.getType()) { - res.add(tr.getCode()); + res.add(tr.getWorkingCode()); } } return res; @@ -1928,7 +1928,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat boolean ok = false; CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); for (TypeRefComponent type : container.getType()) { - if (!ok && type.getCode().equals("Reference")) { + if (!ok && type.getWorkingCode().equals("Reference")) { // we validate as much as we can. First, can we infer a type from the profile? if (!type.hasTargetProfile() || type.hasTargetProfile("http://hl7.org/fhir/StructureDefinition/Resource")) ok = true; @@ -2105,7 +2105,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private String describeTypes(List types) { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); for (TypeRefComponent t : types) { - b.append(t.getCode()); + b.append(t.getWorkingCode()); } return b.toString(); } @@ -2332,7 +2332,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private StructureDefinition getProfileForType(String type, List list) { for (TypeRefComponent tr : list) { - String url = tr.getCode(); + String url = tr.getWorkingCode(); if (!Utilities.isAbsoluteUrl(url)) url = "http://hl7.org/fhir/StructureDefinition/" + url; long t = System.nanoTime(); @@ -2640,7 +2640,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private ElementDefinition resolveType(String type, List list) { for (TypeRefComponent tr : list) { - String url = tr.getCode(); + String url = tr.getWorkingCode(); if (!Utilities.isAbsoluteUrl(url)) url = "http://hl7.org/fhir/StructureDefinition/" + url; long t = System.nanoTime(); @@ -2734,7 +2734,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (!criteriaElement.hasType() || criteriaElement.getType().size()==1) { if (discriminator.contains("[")) discriminator = discriminator.substring(0, discriminator.indexOf('[')); - type = criteriaElement.getType().get(0).getCode(); + type = criteriaElement.getType().get(0).getWorkingCode(); } else if (criteriaElement.getType().size() > 1) { throw new DefinitionException("Discriminator (" + discriminator + ") is based on type, but slice " + ed.getId() + " in "+profile.getUrl()+" has multiple types: "+criteriaElement.typeSummary()); } else @@ -3978,14 +3978,14 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L ei.element.setUserData("elementSupported", "N"); } - if (ei.definition.getType().size() == 1 && !"*".equals(ei.definition.getType().get(0).getCode()) && !"Element".equals(ei.definition.getType().get(0).getCode()) - && !"BackboneElement".equals(ei.definition.getType().get(0).getCode())) { - type = ei.definition.getType().get(0).getCode(); + if (ei.definition.getType().size() == 1 && !"*".equals(ei.definition.getType().get(0).getWorkingCode()) && !"Element".equals(ei.definition.getType().get(0).getWorkingCode()) + && !"BackboneElement".equals(ei.definition.getType().get(0).getWorkingCode())) { + type = ei.definition.getType().get(0).getWorkingCode(); // Excluding reference is a kludge to get around versioning issues if (ei.definition.getType().get(0).hasProfile()) profiles.add(ei.definition.getType().get(0).getProfile().get(0).getValue()); - } else if (ei.definition.getType().size() == 1 && "*".equals(ei.definition.getType().get(0).getCode())) { + } else if (ei.definition.getType().size() == 1 && "*".equals(ei.definition.getType().get(0).getWorkingCode())) { String prefix = tail(ei.definition.getPath()); assert prefix.endsWith("[x]"); type = ei.name.substring(prefix.length() - 3); @@ -4004,8 +4004,8 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L else { prefix = prefix.substring(0, prefix.length() - 3); for (TypeRefComponent t : ei.definition.getType()) - if ((prefix + Utilities.capitalize(t.getCode())).equals(ei.name)) { - type = t.getCode(); + if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.name)) { + type = t.getWorkingCode(); // Excluding reference is a kludge to get around versioning issues if (t.hasProfile() && !type.equals("Reference")) profiles.add(t.getProfile().get(0).getValue()); @@ -4013,7 +4013,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L } if (type == null) { TypeRefComponent trc = ei.definition.getType().get(0); - if (trc.getCode().equals("Reference")) + if (trc.getWorkingCode().equals("Reference")) type = "Reference"; else rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, @@ -4021,7 +4021,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L } } else if (ei.definition.getContentReference() != null) { typeDefn = resolveNameReference(profile.getSnapshot(), ei.definition.getContentReference()); - } else if (ei.definition.getType().size() == 1 && ("Element".equals(ei.definition.getType().get(0).getCode()) || "BackboneElement".equals(ei.definition.getType().get(0).getCode()))) { + } else if (ei.definition.getType().size() == 1 && ("Element".equals(ei.definition.getType().get(0).getWorkingCode()) || "BackboneElement".equals(ei.definition.getType().get(0).getWorkingCode()))) { if (ei.definition.getType().get(0).hasProfile()) { CanonicalType pu = ei.definition.getType().get(0).getProfile().get(0); if (pu.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT)) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ProfileValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ProfileValidator.java index 7a0247507..53ae98d3d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ProfileValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ProfileValidator.java @@ -108,7 +108,7 @@ public class ProfileValidator extends BaseValidator { warning(errors, IssueType.BUSINESSRULE, diffElement.getId(), !checkMustSupport || snapElement.hasMustSupport(), "Elements included in the differential should declare mustSupport"); if (checkAggregation) { for (TypeRefComponent type : snapElement.getType()) { - if ("http://hl7.org/fhir/Reference".equals(type.getCode()) || "http://hl7.org/fhir/canonical".equals(type.getCode())) { + if ("http://hl7.org/fhir/Reference".equals(type.getWorkingCode()) || "http://hl7.org/fhir/canonical".equals(type.getWorkingCode())) { warning(errors, IssueType.BUSINESSRULE, diffElement.getId(), type.hasAggregation(), "Elements with type Reference or canonical should declare aggregation"); } } @@ -126,7 +126,7 @@ public class ProfileValidator extends BaseValidator { } private void checkExtensions(StructureDefinition profile, List errors, String kind, ElementDefinition ec) { - if (!ec.getType().isEmpty() && "Extension".equals(ec.getType().get(0).getCode()) && ec.getType().get(0).hasProfile()) { + if (!ec.getType().isEmpty() && "Extension".equals(ec.getType().get(0).getWorkingCode()) && ec.getType().get(0).hasProfile()) { String url = ec.getType().get(0).getProfile().get(0).getValue(); StructureDefinition defn = context.fetchResource(StructureDefinition.class, url); rule(errors, IssueType.BUSINESSRULE, profile.getId(), defn != null, "Unable to find Extension '"+url+"' referenced at "+profile.getUrl()+" "+kind+" "+ec.getPath()+" ("+ec.getSliceName()+")");